<!DOCTYPE html>
<html>
    <head>
        <meta charset='utf-8'>
        <meta name='viewport' content='width=device-width, initial-scale=1'>
        <title>
            Python 3 教程
        </title>
        <link rel='stylesheet' href='css/themes/default/jquery.mobile-1.4.5.min.css'>
        <script src='js/jquery.js'>
        </script>
        <script src='js/jquery.mobile-1.4.5.min.js'>
        </script>
        <script>
            function navNext(nurl) {
                nextHerf = "#" + nurl;
                jQuery.mobile.changePage(nextHerf);
            }
        </script>
    </head>
    
    <body>
<div data-role='page' id='tutorial.html'><div data-role='header'><h1>Python 3 教程</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('interpreter.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python 3 教程</h1>
<div class="tutintro"> 
<img src="python3.png" alt="python3" width="150" height="81" class="alignnone size-full wp-image-7280" />
<p>Python的3.0版本，常被称为Python 3000，或简称Py3k。相对于Python的早期版本，这是一个较大的升级。为了不带入过多的累赘，Python 3.0在设计的时候没有考虑向下兼容。</p>
<p>Python 介绍及安装教程我们在<a href="/python/python-tutorial.html" target="_blank">Python 2.X版本的教程</a>中已有介绍，这里就不再赘述。<a/>
<p>你也可以点击<a target="_top" href="python-2x-3x.html"> Python2.x与3​​.x版本区别 </a>来查看两者的不同。</p>
<p>本教程主要针对Python 3.x版本的学习，如果你使用的是Python 2.x版本请移步至<a href="/python/python-tutorial.html" target="_blank">Python 2.X版本的教程</a>。
</div>
<hr>
<h2>查看python版本</h2>
<p>我们可以使用以下命令来查看我们使用的Python版本：</p>
<pre>
python -V
</pre>
<p>以上命令执行结果如下：</p>
<pre>
Python 3.3.2
</pre>
<p>你也可以进入Python的交互式编程模式，查看版本：</p>
<pre>
Python 3.3.2 (v3.3.2:d047928ae3f6, May 16 2013, 00:03:43) [MSC v.1600 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
&gt;&gt;&gt; 
</pre>
<hr>
<h2>第一个Python3.x程序</h2>
<p>对于大多数程序语言，第一个入门编程代码便是"Hello World！"，以下代码为使用Python输出"Hello World！"：</p>
<div class="example"> 
<h2 class="example">实例(Python 3.0+)</h2> 
<div class="example_code">
#!/usr/bin/python<br>
print("Hello, World!");
</div><br>
<a target="_blank" href="/try/showpy.php?filename=HelloWorld&language=py3" class="showbtn">运行实例 »</a>
</div>
<p>你可以将以上代码保存在hello.py文件中并使用python命令执行该脚本文件。</p>
<pre>
python hello.py
</pre>
<p>以上命令输出结果为：</p>
<pre>
Hello, World!
</pre>			
			
			</div></div><div data-role='page' id='interpreter.html'><div data-role='header'><h1>解释器</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('comment.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
<h1>Python3 解释器</h1>
<p>
Linux/Unix的系统上，一般默认的 python 版本为 2.x，我们可以将 python3.x 安装在 <strong>/usr/local/python3</strong> 目录中。
</p>
<p>安装完成后，我们可以将路径 <strong>/usr/local/python3/bin</strong> 添加到您的 Linux/Unix 操作系统的环境变量中，这样您就可以通过 shell 终端输入下面的命令来启动 Python3 。
<pre>
$ PATH=$PATH:/usr/local/python3/bin/python3    # 设置环境变量
$ python3 --version
Python 3.4.0
</pre>
<p>在Window系统下你可以通过以下命令来设置Python的环境变量，假设你的Python安装在 C:\Python34 下:</p>
<pre>
set path=%path%;C:\python34
</pre>
<hr>
<h2>
交互式编程</h2>
<p>我们可以在命令提示符中输入"Python"命令来启动Python解释器：</p>
<pre>
$ python3
</pre>
<p>执行以上命令后，出现如下窗口信息：</p>
<pre>
$ python3
Python 3.4.0 (default, Apr 11 2014, 13:05:11) 
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
&gt;&gt;&gt; 
</pre>
<p>在 python 提示符中输入以下语句，然后按回车键查看运行效果：</p>
<pre>
print ("Hello, Python!");
</pre>
<p>以上命令执行结果如下：</p>
<pre>
Hello, Python!
</pre>
<p>当键入一个多行结构时，续行是必须的。我们可以看下如下 if 语句：</p>
<pre>
&gt;&gt;&gt; flag = True
&gt;&gt;&gt; if flag :
...     print("flag 条件为 True!")
... 
flag 条件为 True!
</pre>
<hr>
<h2>
脚本式编程</h2>
<p>将如下代码拷贝至 <strong>hello.py</strong>文件中：</p>
<pre>
print ("Hello, Python!");
</pre>
<p>通过以下命令执行该脚本：</p>
<pre>
python3 hello.py
</pre>
<p>输出结果为：</p>
<pre>
Hello, Python!
</pre>
<p>
在Linux/Unix系统中，你可以在脚本顶部添加以下命令让Python脚本可以像SHELL脚本一样可直接执行：
</p>
<pre>
#! /usr/bin/env python3
</pre>
<p>然后修改脚本权限，使其有执行权限，命令如下：</p>
<pre>
$ chmod +x hello.py
</pre>
<p>执行以下命令：</p>
<pre>
./hello.py
</pre>
<p>输出结果为：</p>
<pre>
Hello, Python!
</pre>
<p>
</div></div><div data-role='page' id='comment.html'><div data-role='header'><h1>注释</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('number.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 注释</h1>
<p>确保对模块, 函数, 方法和行内注释使用正确的风格</p>
<p>Python中的注释有单行注释和多行注释：</p>
<p>Python中单行注释以#开头，例如：：</p>
<pre>
# 这是一个注释
print("Hello, World!") 
</pre>
<p>多行注释用三个单引号（'''）或者三个双引号（"""）将注释括起来，例如:</p>
<p>1、单引号（'''）</p>
<pre>
#!/usr/bin/python3 
'''
这是多行注释，用三个单引号
这是多行注释，用三个单引号 
这是多行注释，用三个单引号
'''
print("Hello, World!") 
</pre>
<p>2、双引号（'''）</p>
<pre>
#!/usr/bin/python3 
"""
这是多行注释，用三个单引号
这是多行注释，用三个单引号 
这是多行注释，用三个单引号
"""
print("Hello, World!") 
</pre>			
			
			</div></div><div data-role='page' id='number.html'><div data-role='header'><h1>数字(Number)</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('string.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 数字(Number)</h1>
<p>Python 数字数据类型用于存储数值。</p>
<p>数据类型是不允许改变的,这就意味着如果改变数字数据类型得值，将重新分配内存空间。</p>

<p>以下实例在变量赋值时 Number 对象将被创建：</p>
<pre>
var1 = 1
var2 = 10
</pre>
<p>您也可以使用del语句删除一些数字对象引用。 </p>
<p>del语句的语法是：</p>
<pre>
del var1[,var2[,var3[....,varN]]]]
</pre>
<p>您可以通过使用del语句删除单个或多个对象，例如：</p>
<pre>
del var
del var_a, var_b
</pre>
<p>Python 支持三种不同的数值类型：</p>
<ul>
<li><strong>整型(Int)</strong> - 通常被称为是整型或整数，是正或负整数，不带小数点。Python3 整型是没有限制大小的，可以当作 Long 类型使用，所以 Python3 没有 Python2 的 Long 类型。</li>

<li><strong>浮点型(float)</strong> - 浮点型由整数部分与小数部分组成，浮点型也可以使用科学计数法表示（2.5e2 = 2.5 x 10<sup>2</sup> = 250）</li>
<li><strong>复数( (complex))</strong> - 复数由实数部分和虚数部分构成，可以用a + bj,或者complex(a,b)表示， 复数的实部a和虚部b都是浮点型。</li>
</ul>
<p>我们可以使用十六进制和八进制来代表整数：</p>
<pre>
&gt;&gt;&gt; number = 0xA0F # 十六进制
&gt;&gt;&gt; number
2575

&gt;&gt;&gt; number=0o37 # 八进制
&gt;&gt;&gt; number
31
</pre>
<table class="reference">
<tbody><tr><th>int</th><th>float</th><th>complex</th></tr>
<tr><td>10</td><td>0.0</td><td>3.14j</td></tr>
<tr><td>100</td><td>15.20</td><td>45.j</td></tr>
<tr><td>-786</td><td>-21.9</td><td>9.322e-36j</td></tr>
<tr><td>080</td><td>32.3+e18</td><td>.876j</td></tr>
<tr><td>-0490</td><td>-90.</td><td>-.6545+0J</td></tr>
<tr><td>-0x260</td><td>-32.54e100</td><td>3e+26J</td></tr>
<tr><td>0x69</td><td>70.2-E12</td><td>4.53e-7j</td></tr>
</tbody></table>
<ul>

<li>Python支持复数，复数由实数部分和虚数部分构成，可以用a + bj,或者complex(a,b)表示，
复数的实部a和虚部b都是浮点型。
</li>
</ul>
<br><hr>
<h2>Python 数字类型转换</h2>
<p>有时候，我们需要对数据内置的类型进行转换，数据类型的转换，你只需要将数据类型作为函数名即可。</p>
<ul class="list">
<li><p><b>int(x)</b> 将x转换为一个整数。</p></li>
<li><p><b>float(x)</b> 将x转换到一个浮点数。</p></li>
<li><p> <b>complex(x)</b> 将x转换到一个复数，实数部分为 x，虚数部分为 0。</p></li>
<li><p><b>complex(x, y)</b> 将 x 和 y 转换到一个复数，实数部分为 x，虚数部分为 y。x 和 y 是数字表达式。</p></li>
</ul>
<p>以下实例将浮点数变量 a 转换为整数：</p>
<pre>
&gt;&gt;&gt; a = 1.0
&gt;&gt;&gt; int(a)
1
</pre>
<hr>
<h2>Python 数字运算</h2>
<p>Python 解释器可以作为一个简单的计算器，您可以在解释器里输入一个表达式，它将输出表达式的值。</p>
<p>表达式的语法很直白： +, -, * 和 / 和其它语言（如Pascal或C）里一样。例如：</p>
<pre>
&gt;&gt;&gt; 2 + 2
4
&gt;&gt;&gt; 50 - 5*6
20
&gt;&gt;&gt; (50 - 5*6) / 4
5.0
&gt;&gt;&gt; 8 / 5  # 总是返回一个浮点数
1.6
</pre>
<p><strong>注意：</strong>在不同的机器上浮点运算的结果可能会不一样。</p>
<p>在整数除法中，除法（/）总是返回一个浮点数，如果只想得到整数的结果，丢弃可能的分数部分，可以使用运算符 <b>//</b> ：</p>
<pre>
&gt;&gt;&gt; 17 / 3  # 整数除法返回浮点型
5.666666666666667
&gt;&gt;&gt;
&gt;&gt;&gt; 17 // 3  # 整数除法返回向下取整后的结果
5
&gt;&gt;&gt; 17 % 3  # ％操作符返回除法的余数
2
&gt;&gt;&gt; 5 * 3 + 2 
17
</pre>
<p>
等号（=）用于给变量赋值。赋值之后，除了下一个提示符，解释器不会显示任何结果。
</p>
<pre>
&gt;&gt;&gt; width = 20
&gt;&gt;&gt; height = 5*9
&gt;&gt;&gt; width * height
900
</pre>
<p>Python 可以使用 <b>**</b> 操作来进行幂运算：</p>
<pre>
&gt;&gt;&gt; 5 ** 2  # 5 的平方
25
&gt;&gt;&gt; 2 ** 7  # 2的7次方
128
</pre>
<p>变量在使用前必须先"定义"（即赋予变量一个值），否则会出现错误：</p>
<pre>
&gt;&gt;&gt; n   # 尝试访问一个未定义的变量
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in &lt;module&gt;
NameError: name 'n' is not defined
</pre>
<p>不同类型的数混合运算时会将整数转换为浮点数：</p>
<pre>
&gt;&gt;&gt; 3 * 3.75 / 1.5
7.5
&gt;&gt;&gt; 7.0 / 2
3.5
</pre>
<p>
在交互模式中，最后被输出的表达式结果被赋值给变量 <b>_ </b>。例如：
</p>
<pre>
&gt;&gt;&gt; tax = 12.5 / 100
&gt;&gt;&gt; price = 100.50
&gt;&gt;&gt; price * tax
12.5625
&gt;&gt;&gt; price + _
113.0625
&gt;&gt;&gt; round(_, 2)
113.06
</pre>
<p>此处， <b>_ </b>变量应被用户视为只读变量。
</p>

<br><hr>
<h2>数学函数</h2>
<table class="reference">
<tbody><tr>
<th>函数</th><th>返回值 ( 描述 )</th></tr>
<tr><td><a href="/python3/python3-func-number-abs.html">abs(x)</a></td><td>返回数字的绝对值，如abs(-10) 返回 10</td></tr>
<tr><td><a href="/python3/python3-func-number-ceil.html">ceil(x) </a></td><td>返回数字的上入整数，如math.ceil(4.1) 返回 5</td></tr>
<tr><td><p>cmp(x, y)</p></td>
<td>如果 x &lt; y 返回 -1, 如果 x == y 返回 0, 如果 x &gt; y 返回 1。 <strong>Python 3 已废弃</strong> 。使用 <strong> 使用 (x&gt;y)-(x&lt;y)</strong> 替换。 </td>
</tr>
<tr><td><a href="/python3/python3-func-number-exp.html">exp(x) </a></td><td>返回e的x次幂(e<sup>x</sup>),如math.exp(1) 返回2.718281828459045</td></tr>
<tr><td><a href="/python3/python3-func-number-fabs.html">fabs(x)</a></td><td>返回数字的绝对值，如math.fabs(-10) 返回10.0</td></tr>
<tr><td><a href="/python3/python3-func-number-floor.html">floor(x) </a></td><td>返回数字的下舍整数，如math.floor(4.9)返回 4</td></tr>
<tr><td><a href="/python3/python3-func-number-log.html">log(x) </a></td><td>如math.log(math.e)返回1.0,math.log(100,10)返回2.0</td></tr>
<tr><td><a href="/python3/python3-func-number-log10.html">log10(x) </a></td><td>返回以10为基数的x的对数，如math.log10(100)返回 2.0</td></tr>
<tr><td><a href="/python3/python3-func-number-max.html">max(x1, x2,...) </a></td><td>返回给定参数的最大值，参数可以为序列。</td></tr>
<tr><td><a href="/python3/python3-func-number-min.html">min(x1, x2,...) </a></td><td>返回给定参数的最小值，参数可以为序列。</td></tr>
<tr><td><a href="/python3/python3-func-number-modf.html">modf(x) </a></td><td>返回x的整数部分与小数部分，两部分的数值符号与x相同，整数部分以浮点型表示。</td></tr>
<tr><td><a href="/python3/python3-func-number-pow.html">pow(x, y)</a></td><td> x**y 运算后的值。</td></tr>
<tr><td><a href="/python3/python3-func-number-round.html">round(x [,n])</a></td><td>返回浮点数x的四舍五入值，如给出n值，则代表舍入到小数点后的位数。</td></tr>
<tr><td><a href="/python3/python3-func-number-sqrt.html">sqrt(x) </a></td><td>返回数字x的平方根，数字可以为负数，返回类型为实数，如math.sqrt(4)返回 2+0j</td></tr>
</tbody></table>
<br><hr>
<h2>随机数函数</h2>
<p>随机数可以用于数学，游戏，安全等领域中，还经常被嵌入到算法中，用以提高算法效率，并提高程序的安全性。</p>
<p>Python包含以下常用随机数函数：</p>
<table class="reference">
<tbody><tr>
<th>函数</th><th>描述</th></tr>
<tr><td><a href="/python3/python3-func-number-choice.html">choice(seq)</a></td><td>从序列的元素中随机挑选一个元素，比如random.choice(range(10))，从0到9中随机挑选一个整数。</td></tr>
<tr><td><a href="/python3/python3-func-number-randrange.html">randrange ([start,] stop [,step]) </a></td><td>从指定范围内，按指定基数递增的集合中获取一个随机数，基数缺省值为1</td></tr>
<tr><td><a href="/python3/python3-func-number-random.html">random() </a></td><td> 随机生成下一个实数，它在[0,1)范围内。</td></tr>
<tr><td><a href="/python3/python3-func-number-seed.html">seed([x]) </a></td><td>改变随机数生成器的种子seed。如果你不了解其原理，你不必特别去设定seed，Python会帮你选择seed。</td></tr>
<tr><td><a href="/python3/python3-func-number-shuffle.html">shuffle(lst) </a></td><td>将序列的所有元素随机排序</td></tr>
<tr><td><a href="/python3/python3-func-number-uniform.html">uniform(x, y)</a></td><td>随机生成下一个实数，它在[x,y]范围内。</td></tr>
</tbody></table>
<br><hr>
<h2>三角函数</h2>
<p>
Python包括以下三角函数：</p>
<table class="reference">
<tbody><tr>
<th>函数</th><th>描述</th></tr>
<tr><td><a href="/python3/python3-func-number-acos.html">acos(x)</a></td><td>返回x的反余弦弧度值。</td></tr>
<tr><td><a href="/python3/python3-func-number-asin.html">asin(x)</a></td><td>返回x的反正弦弧度值。<td></tr>
<tr><td><a href="/python3/python3-func-number-atan.html">atan(x)</a></td><td>返回x的反正切弧度值。</td></tr>
<tr><td><a href="/python3/python3-func-number-atan2.html">atan2(y, x)</a></td><td>返回给定的 X 及 Y 坐标值的反正切值。</td></tr>
<tr><td><a href="/python3/python3-func-number-cos.html">cos(x)</a></td><td>返回x的弧度的余弦值。</td></tr>
<tr><td><a href="/python3/python3-func-number-hypot.html">hypot(x, y)</a></td><td>返回欧几里德范数 sqrt(x*x + y*y)。 </td></tr>
<tr><td><a href="/python3/python3-func-number-sin.html">sin(x)</a></td><td>返回的x弧度的正弦值。</td></tr>
<tr><td><a href="/python3/python3-func-number-tan.html">tan(x)</a></td><td>返回x弧度的正切值。</td></tr>
<tr><td><a href="/python3/python3-func-number-degrees.html">degrees(x)</a></td><td>将弧度转换为角度,如degrees(math.pi/2) ，  返回90.0</td></tr>
<tr><td><a href="/python3/python3-func-number-radians.html">radians(x)</a></td><td>将角度转换为弧度</td></tr>
</tbody></table>
<br><hr>
<h2>数学常量</h2>
<table class="reference">
<tbody><tr>
<th>常量</th><th>描述</th></tr>
<tr><td>pi</td><td>数学常量 pi（圆周率，一般以π来表示）</td></tr>
<tr><td>e</td><td>数学常量 e，e即自然常数（自然常数）。</td></tr>
</tbody></table>			
			
			</div></div><div data-role='page' id='string.html'><div data-role='header'><h1>字符串</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('list.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 <span class="color_h1">字符串</span></h1>
<p>字符串是 Python 中最常用的数据类型。我们可以使用引号('或")来创建字符串。</p>

<p>创建字符串很简单，只要为变量分配一个值即可。例如：</p>
<pre>
var1 = 'Hello World!'
var2 = "Runoob"
</pre>
<hr>
<h2>Python 访问字符串中的值</h2>
<p>Python 不支持单字符类型，单字符也在Python也是作为一个字符串使用。</p>
<p>Python 访问子字符串，可以使用方括号来截取字符串，如下实例：</p>
<pre>
#!/usr/bin/python3

var1 = 'Hello World!'
var2 = "Runoob"

print ("var1[0]: ", var1[0])
print ("var2[1:5]: ", var2[1:5])
</pre>
<p>以上实例执行结果：</p>
<pre>
var1[0]:  H
var2[1:5]:  unoo
</pre>
<hr>
<h2>Python字符串更新</h2>
<p>你可以对已存在的字符串进行修改，并赋值给另一个变量，如下实例：</p>
<pre>
#!/usr/bin/python3

var1 = 'Hello World!'

print ("已更新字符串 : ", var1[:6] + 'Runoob!')
</pre>
<p>以上实例执行结果</p>

<pre>
已更新字符串 :  Hello Runoob!
</pre><hr>
<h2>Python转义字符</h2>
<p>在需要在字符中使用特殊字符时，python用反斜杠(\)转义字符。如下表：</p>
<table class="reference">
<thead>
<tr>
<th>转义字符</th><th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>\(在行尾时)</td>
<td>续行符</td>
</tr>
<tr>
<td>\\</td>
<td>反斜杠符号</td>
</tr>
<tr>
<td>\'</td>
<td>单引号</td>
</tr>
<tr>
<td>\"</td>
<td>双引号</td>
</tr>
<tr>
<td>\a</td>
<td>响铃</td>
</tr>
<tr>
<td>\b</td>
<td>退格(Backspace)</td>
</tr>
<tr>
<td>\e</td>
<td>转义</td>
</tr>
<tr>
<td>\000</td>
<td>空</td>
</tr>
<tr>
<td>\n</td>
<td>换行</td>
</tr>
<tr>
<td>\v</td>
<td>纵向制表符</td>
</tr>
<tr>
<td>\t</td>
<td>横向制表符</td>
</tr>
<tr>
<td>\r</td>
<td>回车</td>
</tr>
<tr>
<td>\f</td>
<td>换页</td>
</tr>
<tr>
<td>\oyy</td>
<td>八进制数，yy代表的字符，例如：\o12代表换行</td>
</tr>
<tr>
<td>\xyy</td>
<td>十六进制数，yy代表的字符，例如：\x0a代表换行</td>
</tr>
<tr>
<td>\other</td>
<td>其它的字符以普通格式输出</td>
</tr>
</tbody>
</table><hr>
<h2>Python字符串运算符</h2>
<p>下表实例变量a值为字符串 "Hello"，b变量值为 "Python"：</p>
<table class="reference">
<tbody><tr>
<th width="10%">操作符</th><th>描述</th><th>实例</th>
</tr>
<tr>
<td>+</td><td>字符串连接</td><td> a + b 输出结果： HelloPython</td>
</tr>
<tr>
<td>*</td><td>重复输出字符串</td><td> a*2 输出结果：HelloHello</td>
</tr>
<tr>
<td>[]</td><td>通过索引获取字符串中字符</td><td> a[1] 输出结果 <b>e</b></td>
</tr>
<tr>
<td>[ : ]</td><td>截取字符串中的一部分</td><td> a[1:4] 输出结果 <b>ell</b></td>
</tr>
<tr>
<td>in</td><td>成员运算符 - 如果字符串中包含给定的字符返回 True </td><td> <b>H in a</b> 输出结果 1</td>
</tr>
<tr>
<td>not in </td><td>成员运算符 - 如果字符串中不包含给定的字符返回 True </td><td> <b>M not in a</b> 输出结果 1</td>
</tr>
<tr>
<td>r/R</td><td>原始字符串 - 原始字符串：所有的字符串都是直接按照字面的意思来使用，没有转义特殊或不能打印的字符。

原始字符串除在字符串的第一个引号前加上字母"r"（可以大小写）以外，与普通字符串有着几乎完全相同的语法。</td><td> <b>print r'\n'</b> prints \n 和 <b>print R'\n'</b> prints \n  </td>
</tr>
<tr>
<td>%</td><td>格式字符串</td><td>请看下一节内容。</td>
</tr>
</tbody></table>
<h3>实例</h3>
<pre>
#!/usr/bin/python3

a = "Hello"
b = "Python"

print("a + b 输出结果：", a + b)
print("a * 2 输出结果：", a * 2)
print("a[1] 输出结果：", a[1])
print("a[1:4] 输出结果：", a[1:4])

if( "H" in a) :
    print("H 在变量 a 中")
else :
	print("H 不在变量 a 中")

if( "M" not in a) :
    print("M 不在变量 a 中")
else :
	print("M 在变量 a 中")

print (r'\n')
print (R'\n')
</pre>
<p>以上实例输出结果为：</p>
<pre>
a + b 输出结果： HelloPython
a * 2 输出结果： HelloHello
a[1] 输出结果： e
a[1:4] 输出结果： ell
H 在变量 a 中
M 不在变量 a 中
\n
\n
</pre>



<hr>
<h2>Python字符串格式化</h2>
<p>Python 支持格式化字符串的输出 。尽管这样可能会用到非常复杂的表达式，但最基本的用法是将一个值插入到一个有字符串格式符 %s 的字符串中。</p>

<p>在 Python 中，字符串格式化使用与 C 中 sprintf 函数一样的语法。</p>
<p>如下实例：</p>
<pre>
#!/usr/bin/python3

print ("我叫 %s 今年 %d 岁!" % ('小明', 10))
</pre>
<p>以上实例输出结果：</p>
<pre>
我叫 小明 今年 10 岁!
</pre>
<p>python字符串格式化符号:</p>
<table class="reference">
<tbody<tr><th>
&nbsp;&nbsp;&nbsp; 符&nbsp;&nbsp; 号</th>
<th>描述</th></tr><tr><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %c</font></td><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;格式化字符及其ASCII码</font></td></tr><tr><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %s</font></td><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;格式化字符串</font></td></tr><tr><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %d</font></td><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;格式化整数</font></td></tr><tr><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %u</font></td><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;格式化无符号整型</font></td></tr><tr><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %o</font></td><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;格式化无符号八进制数</font></td></tr><tr><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %x</font></td><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;格式化无符号十六进制数</font></td></tr><tr><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %X</font></td><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;格式化无符号十六进制数（大写）</font></td></tr><tr><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %f</font></td><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;格式化浮点数字，可指定小数点后的精度</font></td></tr><tr><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %e</font></td><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;用科学计数法格式化浮点数</font></td></tr><tr><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %E</font></td><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;作用同%e，用科学计数法格式化浮点数</font></td></tr><tr><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %g</font></td><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;%f和%e的简写</font></td></tr><tr><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %G</font></td><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;%f 和 %E 的简写</font></td></tr><tr><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; %p</font></td><td><font face="宋体" size="2" style="line-height: 23px; ">&nbsp;用十六进制数格式化变量的地址</font></td></tr></tbody></table>
<p>格式化操作符辅助指令:</p>
<table class="reference">
<tbody><tr>
<th>符号</th><th>功能</th>
</tr>
<tr><td>*</td><td>定义宽度或者小数点精度 </td></tr>
<tr><td>-</td><td>用做左对齐 </td></tr>
<tr><td>+</td><td>在正数前面显示加号( + ) </td></tr>
<tr><td>&lt;sp&gt;</td><td>在正数前面显示空格 </td></tr>
<tr><td>#</td><td> 在八进制数前面显示零('0')，在十六进制前面显示'0x'或者'0X'(取决于用的是'x'还是'X')</td></tr>
<tr><td>0</td><td> 显示的数字前面填充'0'而不是默认的空格 </td></tr>
<tr><td>%</td><td> '%%'输出一个单一的'%' </td></tr>
<tr><td>(var)</td><td>映射变量(字典参数) </td></tr>
<tr><td>m.n.</td><td>  m 是显示的最小总宽度,n 是小数点后的位数(如果可用的话)</td></tr>
</tbody></table>
<hr>
<h2>Python三引号 </h2>
<p>python三引号允许一个字符串跨多行，字符串中可以包含换行符、制表符以及其他特殊字符。实例如下</p>
<pre>
#!/usr/bin/python3

para_str = """这是一个多行字符串的实例
多行字符串可以使用制表符
TAB ( \t )。
也可以使用换行符 [ \n ]。
"""
print (para_str)
</pre>
<p>以上实例执行结果为：</p>
<pre>
这是一个多行字符串的实例
多行字符串可以使用制表符
TAB (    )。
也可以使用换行符 [ 
 ]。

</pre>
<p>三引号让程序员从引号和特殊字符串的泥潭里面解脱出来，自始至终保持一小块字符串的格式是所谓的WYSIWYG（所见即所得）格式的。</p>


<p>一个典型的用例是，当你需要一块HTML或者SQL时，这时用字符串组合，特殊字符串转义将会非常的繁琐。</p>
<pre>
errHTML = '''
&lt;HTML&gt;&lt;HEAD&gt;&lt;TITLE&gt;
Friends CGI Demo&lt;/TITLE&gt;&lt;/HEAD&gt;
&lt;BODY&gt;&lt;H3&gt;ERROR&lt;/H3&gt;
&lt;B&gt;%s&lt;/B&gt;&lt;P&gt;
&lt;FORM&gt;&lt;INPUT TYPE=button VALUE=Back
ONCLICK="window.history.back()"&gt;&lt;/FORM&gt;
&lt;/BODY&gt;&lt;/HTML&gt;
'''
cursor.execute('''
CREATE TABLE users (  
login VARCHAR(8), 
uid INTEGER,
prid INTEGER)
''')
</pre>
<hr>
<h2>Unicode 字符串</h2>
<p>
在Python2中，普通字符串是以8位ASCII码进行存储的，而Unicode字符串则存储为16位unicode字符串，这样能够表示更多的字符集。使用的语法是在字符串前面加上前缀 <b>u</b>。
</p><p>
在Python3中，所有的字符串都是Unicode字符串。
</p>
<hr>
<h2>Python 的字符串内建函数</h2>
<p>Python 的字符串常用内建函数如下：</p>
</p>
<table class="reference">
<tbody><tr>
<th style="width:5%">序号</th><th>方法及描述</th></tr>
<tr><td>1</td><td><p><a href="/python3/python3-string-capitalize.html">capitalize()</a><br>将字符串的第一个字符转换为大写</p></td></tr>
<tr><td>2</td><td><p><a href="/python3/python3-string-center.html">center(width, fillchar)</a></p><br>
返回一个指定的宽度 width 居中的字符串，fillchar 为填充的字符，默认为空格。</td>
</tr>
<tr><td>3</td><td><p><a href="/python3/python3-string-count.html">count(str, beg= 0,end=len(string))</a></p><br>返回 str 在 string 里面出现的次数，如果 beg 或者 end 指定则返回指定范围内 str 出现的次数</td></tr>
<tr><td>4</td><td><p><a href="/python3/python3-string-decode.html">decode(encoding='UTF-8',errors='strict')</a></p><br>使用指定编码来解码字符串。默认编码为字符串编码。</td></tr>
<tr><td>5</td><td><p><a href="/python3/python3-string-encode.html">encode(encoding='UTF-8',errors='strict')</a></p><br>以 encoding 指定的编码格式编码字符串，如果出错默认报一个ValueError 的异常，除非 errors 指定的是'ignore'或者'replace'</td></tr>
<tr><td>6</td><td><p><a href="/python3/python3-string-endswith.html">endswith(suffix, beg=0, end=len(string))</a><br>检查字符串是否以 obj 结束，如果beg 或者 end 指定则检查指定的范围内是否以 obj 结束，如果是，返回 True,否则返回 False.</p></td></tr>
<tr><td>7</td><td><p><a href="/python3/python3-string-expandtabs.html">expandtabs(tabsize=8)</a></p><br>把字符串 string 中的 tab 符号转为空格，tab 符号默认的空格数是 8 。</td></tr>
<tr><td>8</td><td><p><a href="/python3/python3-string-find.html">find(str, beg=0 end=len(string))</a></p><br>检测 str 是否包含在字符串中 中，如果 beg 和 end 指定范围，则检查是否包含在指定范围内，如果是返回开始的索引值，否则返回-1</td></tr>
<tr><td>9</td><td><p><a href="/python3/python3-string-index.html">index(str, beg=0, end=len(string))</a></p><br>跟find()方法一样，只不过如果str不在字符串中会报一个异常.</td></tr>
<tr><td>10</td><td><p><a href="/python3/python3-string-isalnum.html">isalnum()</a></p><br>如果字符串至少有一个字符并且所有字符都是字母或数字则返
回 True,否则返回 False</td></tr>
<tr><td>11</td><td><p><a href="/python3/python3-string-isalpha.html">isalpha()</a></p><br>如果字符串至少有一个字符并且所有字符都是字母则返回 True,
否则返回 False</td></tr>
<tr><td>12</td><td><p><a href="/python3/python3-string-isdigit.html">isdigit()</a></p><br>如果字符串只包含数字则返回 True 否则返回 False..</td></tr>
<tr><td>13</td><td><p><a href="/python3/python3-string-islower.html">islower()</a></p><br>如果字符串中包含至少一个区分大小写的字符，并且所有这些(区分大小写的)字符都是小写，则返回 True，否则返回 False</td></tr>
<tr><td>14</td><td><p><a href="/python3/python3-string-isnumeric.html">isnumeric()</a></p><br>如果字符串中只包含数字字符，则返回 True，否则返回 False</td></tr>
<tr><td>15</td><td><p><a href="/python3/python3-string-isspace.html">isspace()</a></p><br>如果字符串中只包含空格，则返回 True，否则返回 False.</td></tr>
<tr><td>16</td><td><p><a href="/python3/python3-string-istitle.html">istitle()</a></p><br>	
如果字符串是标题化的(见 title())则返回 True，否则返回 False</td></tr>
<tr><td>17</td><td><p><a href="/python3/python3-string-isupper.html">isupper()</a></p><br>如果字符串中包含至少一个区分大小写的字符，并且所有这些(区分大小写的)字符都是大写，则返回 True，否则返回 False</td></tr>
<tr><td>18</td><td><p><a href="/python3/python3-string-join.html">join(seq)</a></p><br>以指定字符串作为分隔符，将 seq 中所有的元素(的字符串表示)合并为一个新的字符串</td></tr>
<tr><td>19</td><td><p><a href="/python3/python3-string-len.html">len(string)</a></p><br>返回字符串长度</td></tr>
<tr><td>20</td><td><p><a href="/python3/python3-string-ljust.html">ljust(width[, fillchar])</a></p><br>返回一个原字符串左对齐,并使用 fillchar 填充至长度 width 的新字符串，fillchar 默认为空格。</td></tr>
<tr><td>21</td><td><p><a href="/python3/python3-string-lower.html">lower()</a></p><br>转换字符串中所有大写字符为小写.</td></tr>
<tr><td>22</td><td><p><a href="/python3/python3-string-lstrip.html">lstrip()</a></p><br>截掉字符串左边的空格</td></tr>
<tr><td>23</td><td><p><a href="/python3/python3-string-maketrans.html">maketrans()</a></p><br>创建字符映射的转换表，对于接受两个参数的最简单的调用方式，第一个参数是字符串，表示需要转换的字符，第二个参数也是字符串表示转换的目标。</td></tr>
<tr><td>24</td><td><p><a href="/python3/python3-string-max.html">max(str)</a></p><br>返回字符串 str 中最大的字母。</td></tr>
<tr><td>25</td><td><p><a href="/python3/python3-string-min.html">min(str)</a></p><br>返回字符串 str 中最小的字母。</td></tr>
<tr><td>26</td><td><p><a href="/python3/python3-string-replace.html">replace(old, new [, max])</a></p><br>把 将字符串中的 str1 替换成 str2,如果 max 指定，则替换不超过 max 次。</td></tr>
<tr><td>27</td><td><p><a href="/python3/python3-string-rfind.html">rfind(str, beg=0,end=len(string))</a></p><br>类似于 find()函数，不过是从右边开始查找.</td></tr>
<tr><td>28</td><td><p><a href="/python3/python3-string-rindex.html">rindex( str, beg=0, end=len(string))</a></p><br>类似于 index()，不过是从右边开始.</td></tr>
<tr><td>29</td><td><p><a href="/python3/python3-string-rjust.html">rjust(width,[, fillchar])</a></p><br>返回一个原字符串右对齐,并使用fillchar(默认空格）填充至长度 width 的新字符串</td></tr>
<tr><td>30</td><td><p><a href="/python3/python3-string-rstrip.html">rstrip()</a></p><br>删除字符串字符串末尾的空格.</td></tr>
<tr><td>31</td><td><p><a href="/python3/python3-string-split.html">split(str="", num=string.count(str))</a></p><br>num=string.count(str))
以 str 为分隔符截取字符串，如果 num 有指定值，则仅截取 num 个子字符串</td></tr>
<tr><td>32</td><td><p><a href="/python3/python3-string-splitlines.html">splitlines( num=string.count('\n'))</a></p><br>按照行分隔，返回一个包含各行作为元素的列表，如果 num 指定则仅切片 num 个行.</td></tr>
<tr><td>33</td><td><p><a href="/python3/python3-string-startswith.html">startswith(str, beg=0,end=len(string))</a></p><br>检查字符串是否是以 obj 开头，是则返回 True，否则返回 False。如果beg 和 end 指定值，则在指定范围内检查。</td></tr>
<tr><td>34</td><td><p><a href="/python3/python3-string-strip.html">strip([chars])</a></p><br>在字符串上执行 lstrip()和 rstrip()</td></tr>
<tr><td>35</td><td><p><a href="/python3/python3-string-swapcase.html">swapcase()</a></p><br>将字符串中大写转换为小写，小写转换为大写</td></tr>
<tr><td>36</td><td><p><a href="/python3/python3-string-title.html">title()</a></p><br>返回"标题化"的字符串,就是说所有单词都是以大写开始，其余字母均为小写(见 istitle())</td></tr>
<tr><td>37</td><td><p><a href="/python3/python3-string-translate.html">translate(table, deletechars="")</a></p><br>根据 str 给出的表(包含 256 个字符)转换 string 的字符,
要过滤掉的字符放到 deletechars 参数中</td></tr>
<tr><td>38</td><td><p><a href="/python3/python3-string-upper.html">upper()</a></p><br>	
转换字符串中的小写字母为大写</td></tr>
<tr><td>39</td><td><p><a href="/python3/python3-string-zfill.html">zfill (width)</a></p><br>返回长度为 width 的字符串，原字符串右对齐，前面填充0</td></tr>
<tr><td>40</td><td><p><a href="/python3/python3-string-isdecimal.html">isdecimal()</a></p><br>
检查字符串是否只包含十进制字符，如果是返回 true，否则返回 false。</td></tr>
</tbody></table>			
			
			</div></div><div data-role='page' id='list.html'><div data-role='header'><h1>列表</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('step1.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 <span class="color_h1">列表</span></h1>
<p>序列是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置，或索引，第一个索引是0，第二个索引是1，依此类推。</p>

<p> Python有6个序列的内置类型，但最常见的是列表和元组。</p>

<p>序列都可以进行的操作包括索引，切片，加，乘，检查成员。</p>
<p>此外，Python已经内置确定序列的长度以及确定最大和最小的元素的方法。</p>

<p>列表是最常用的Python数据类型，它可以作为一个方括号内的逗号分隔值出现。</p>
<p>列表的数据项不需要具有相同的类型</p>
<p>创建一个列表，只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示：</p>
<pre>
list1 = ['Google', 'Runoob', 1997, 2000];
list2 = [1, 2, 3, 4, 5 ];
list3 = ["a", "b", "c", "d"];
</pre>
<p>与字符串的索引一样，列表索引从0开始。列表可以进行截取、组合等。</p>
<hr>
<h2>访问列表中的值</h2>
<p>使用下标索引来访问列表中的值，同样你也可以使用方括号的形式截取字符，如下所示：</p>
<pre>
#!/usr/bin/python3

list1 = ['Google', 'Runoob', 1997, 2000];
list2 = [1, 2, 3, 4, 5, 6, 7 ];

print ("list1[0]: ", list1[0])
print ("list2[1:5]: ", list2[1:5])
</pre>
<p> <a href="/try/runcode.php?filename=list_demo&amp;type=python3" target="_blank"><button class="btn example-btn">运行实例 »</button></a> <a href="//static.runoob.com/code/python3/list_demo.py3"><button class="btn">下载</button></a> </p>
<p>以上实例输出结果：</p>
<pre>
list1[0]:  Google
list2[1:5]:  [2, 3, 4, 5]
</pre>
<hr>
<h2>更新列表</h2>
你可以对列表的数据项进行修改或更新，你也可以使用append()方法来添加列表项，如下所示：
<pre>
#!/usr/bin/python3

list = ['Google', 'Runoob', 1997, 2000]

print ("第三个元素为 : ", list[2])
list[2] = 2001
print ("更新后的第三个元素为 : ", list[2])
</pre>
<p><strong>注意：</strong>我们会在接下来的章节讨论append()方法的使用</p>
<p>以上实例输出结果：</p>
<pre>
第三个元素为 :  1997
更新后的第三个元素为 :  2001
</pre>
<hr>
<h2>删除列表元素</h2>
<p>可以使用 del 语句来删除列表的的元素，如下实例：</p>
<pre>
#!/usr/bin/python3

list = ['Google', 'Runoob', 1997, 2000]

print (list)
del list[2]
print ("删除第三个元素 : ", list)
</pre>
<p>以上实例输出结果：</p>
<pre>
删除第三个元素 :  ['Google', 'Runoob', 2000]
</pre>
<p><strong>注意：</strong>我们会在接下来的章节讨论remove()方法的使用</p>

<hr>
<h2>Python列表脚本操作符</h2>
<p>列表对 + 和  * 的操作符与字符串相似。+ 号用于组合列表，* 号用于重复列表。</p>
<p>如下所示：</p>
<table class="reference">
<tbody><tr>
<th>Python 表达式</th><th>结果 </th><th> 描述</th></tr>
<tr><td>len([1, 2, 3])</td><td>3</td><td>长度</td></tr>
<tr><td>[1, 2, 3] + [4, 5, 6]</td><td>[1, 2, 3, 4, 5, 6]</td><td>组合</td></tr>
<tr><td>['Hi!'] * 4</td><td>['Hi!', 'Hi!', 'Hi!', 'Hi!']</td><td>重复</td></tr>
<tr><td>3 in [1, 2, 3]</td><td>True</td><td>元素是否存在于列表中</td></tr>
<tr><td>for x in [1, 2, 3]: print x,</td><td>1 2 3</td><td>迭代</td></tr>
</tbody></table>

<hr>
<h2>Python列表截取与拼接</h2>
<p>Python的列表截取与字符串操作类型，如下所示：</p>
<pre>
L=['Google', 'Runoob', 'Taobao']
</pre>
<p>操作：</p>
<table class="reference">
<tbody><tr>
<th style="width:33%">Python 表达式</th><th style="width:33%">结果 </th><th style="width:33%"> 描述</th></tr>
<tr><td>L[2]</td><td>'Taobao'</td><td>读取第三个元素</td></tr>
<tr><td>L[-2]</td><td>'Runoob'</td><td>从右侧开始读取倒数第二个元素: count from the right</td></tr>
<tr><td>L[1:]</td><td>['Runoob', 'Taobao']</td><td>输出从第二个元素开始后的所有元素</td></tr>
</tbody></table>
<pre>
&gt;&gt;&gt; L=['Google', 'Runoob', 'Taobao']
&gt;&gt;&gt; L[2]
'Taobao'
&gt;&gt;&gt; L[-2]
'Runoob'
&gt;&gt;&gt; L[1:]
['Runoob', 'Taobao']
&gt;&gt;&gt; 
</pre>
<p>列表还支持拼接操作：</p>
<pre>
&gt;&gt;&gt; squares = [1, 4, 9, 16, 25]
&gt;&gt;&gt; squares + [36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
</pre>
<hr>
<h2>嵌套列表</h2>
<p>使用嵌套列表即在列表里创建其它列表，例如：</p>
<pre>
&gt;&gt;&gt; a = ['a', 'b', 'c']
&gt;&gt;&gt; n = [1, 2, 3]
&gt;&gt;&gt; x = [a, n]
&gt;&gt;&gt; x
[['a', 'b', 'c'], [1, 2, 3]]
&gt;&gt;&gt; x[0]
['a', 'b', 'c']
&gt;&gt;&gt; x[0][1]
'b'
</pre>
<hr>
<h2>Python列表函数&方法</h2>
<p>Python包含以下函数:</p>
<table class="reference">
<tbody><tr>
<th style="width:5%">序号</th><th style="width:95%">函数</th></tr>

<tr><td>1</td><td><a href="python3-att-list-len.html">len(list)</a><br>列表元素个数</td></tr>
<tr><td>2</td><td><a href="python3-att-list-max.html">max(list)</a><br>返回列表元素最大值</td></tr>
<tr><td>3</td><td><a href="python3-att-list-min.html">min(list)</a><br>返回列表元素最小值</td></tr>
<tr><td>4</td><td><a href="python3-att-list-list.html">list(seq)</a><br>将元组转换为列表</td></tr>
</tbody></table>
<p>Python包含以下方法:</p>
<table class="reference">
<tbody><tr>
<th style="width:5%">序号</th><th style="width:95%">方法</th></tr>
<tr><td>1</td><td><a href="python3-att-list-append.html">list.append(obj)</a><br>在列表末尾添加新的对象</td></tr>
<tr><td>2</td><td><a href="python3-att-list-count.html">list.count(obj)</a><br>统计某个元素在列表中出现的次数</td></tr>
<tr><td>3</td><td><a href="python3-att-list-extend.html">list.extend(seq)</a><br>在列表末尾一次性追加另一个序列中的多个值（用新列表扩展原来的列表）</td></tr>
<tr><td>4</td><td><a href="python3-att-list-index.html">list.index(obj)</a><br>从列表中找出某个值第一个匹配项的索引位置</td></tr>
<tr><td>5</td><td><a href="python3-att-list-insert.html">list.insert(index, obj)</a><br>将对象插入列表</td></tr>
<tr><td>6</td><td><a href="python3-att-list-pop.html">list.pop(obj=list[-1])</a><br>移除列表中的一个元素（默认最后一个元素），并且返回该元素的值</td></tr>
<tr><td>7</td><td><a href="python3-att-list-remove.html">list.remove(obj)</a><br>移除列表中某个值的第一个匹配项</td></tr>
<tr><td>8</td><td><a href="python3-att-list-reverse.html">list.reverse()</a><br>反向列表中元素</td></tr>
<tr><td>9</td><td><a href="python3-att-list-sort.html">list.sort([func])</a><br>对原列表进行排序</td></tr>
<tr><td>10</td><td><a href="python3-att-list-clear.html">list.clear()</a><br>清空列表</td></tr>
<tr><td>11</td><td><a href="python3-att-list-copy.html">list.copy()</a><br>复制列表</td></tr>
</tbody></table>			
			
			</div></div><div data-role='page' id='step1.html'><div data-role='header'><h1>编程第一步</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('conditional-statements.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 编程第一步</h1>
<p>在前面的教程中我们已经学习了一些 Python3 的基本语法知识，下面我们尝试来写一个斐波纳契数列。</p>
<p>实例如下：</p>
<pre>
#!/usr/bin/python3

# Fibonacci series: 斐波纳契数列
# 两个元素的总和确定了下一个数
a, b = 0, 1
while b &lt; 10:
    print(b)
    a, b = b, a+b
</pre>
<p>执行以上程序，输出结果为：</p>
<pre>
1
1
2
3
5
8
</pre>
<p>
这个例子介绍了几个新特征。
</p>
<ul><li>第一行包含了一个复合赋值：变量 a 和 b 同时得到新值 0 和 1。最后一行再次使用了同样的方法，可以看到，右边的表达式会在赋值变动之前执行。右边表达式的执行顺序是从左往右的。
</li></ul>
<pre>
&gt;&gt;&gt; i = 256*256
&gt;&gt;&gt; print('i 的值为：', i)
i 的值为： 65536
</pre>
<h3>end 关键字</h3>
<p>关键字end可以用于将结果输出到同一行，或者在输出的末尾添加不同的字符，实例如下：
</p>
<pre>
#!/usr/bin/python3

# Fibonacci series: 斐波纳契数列
# 两个元素的总和确定了下一个数
a, b = 0, 1
while b &lt; 1000:
    print(b, end=',')
    a, b = b, a+b
</pre>
<p>执行以上程序，输出结果为：</p>
<pre>
1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,
</pre>			
			
			</div></div><div data-role='page' id='conditional-statements.html'><div data-role='header'><h1>条件控制</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('loop.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
<h1>Python3 条件控制</h1>
<p>Python条件语句是通过一条或多条语句的执行结果（True或者False）来决定执行的代码块。</p><p>
可以通过下图来简单了解条件语句的执行过程:</p>
<p> <img src="if-condition.jpg"> </p>
<hr>
<h2>if 语句</h2>
<p>Python中if语句的一般形式如下所示：</p>
<pre>
if condition_1:
    statement_block_1
elif condition_2:
    statement_block_2
else:
    statement_block_3
</pre>
<ul><li>如果 "condition_1" 为 True 将执行 "statement_block_1" 块语句</li><li>如果 "condition_1" 为False，将判断 "condition_2"</li><li>如果"condition_2"
为 True 将执行 "statement_block_2" 块语句</li><li>如果 "condition_2" 为False，将执行"statement_block_3"块语句</li></ul><p>
Python 中用 <b>elif</b> 代替了 <b>else if</b>，所以if语句的关键字为：<b>if – elif – else</b>。
</p>
<p>
<strong>注意：</strong></p>
<ul><li>
1、每个条件后面要使用冒号（:），表示接下来是满足条件后要执行的语句块。</li><li>
2、使用缩进来划分语句块，相同缩进数的语句在一起组成一个语句块。</li><li>
3、在Python中没有switch – case语句。</li></ul>
<h3>实例</h3>
<p>以下是一个简单的 if 实例：</p>
<pre>
#!/usr/bin/python3

var1 = 100
if var1:
   print ("1 - if 表达式条件为 true")
   print (var1)

var2 = 0
if var2:
   print ("2 - if 表达式条件为 true")
   print (var2)
print ("Good bye!")
</pre>
<p>执行以上代码，输出结果为：</p>
<pre>
1 - if 表达式条件为 true
100
Good bye!
</pre>
<p>从结果可以看到由于变量 var2 为 0，所以对应的 if 内的语句没有执行。</p>
<p>以下实例演示了狗的年龄计算判断：</p>
<pre>
#!/usr/bin/python3

age = int(input("请输入你家狗狗的年龄: "))
print("")
if age &lt; 0:
	print("你是在逗我吧!")
elif age == 1:
	print("相当于 14 岁的人。")
elif age == 2:
	print("相当于 22 岁的人。")
elif age &gt; 2:
	human = 22 + (age -2)*5
	print("对应人类年龄: ", human)

### 退出提示
input('点击 enter 键退出')
</pre>
<p>将以上脚本保存在dog.py文件中，并执行该脚本：</p>
<pre>
$ python3 dog.py 
请输入你家狗狗的年龄: 1

相当于 14 岁的人。
点击 enter 键退出
</pre>
<p>
以下为if中常用的操作运算符:</p>
<table class="reference">
<tbody><tr>
<th>操作符</th>
<th>描述</th>
</tr>
<tr>
<td><code>&lt;</code></td>
<td>小于</td>
</tr>
<tr>
<td><code>&lt;=</code></td>
<td>小于或等于</td>
</tr>
<tr>
<td><code>&gt;</code></td>
<td>大于</td>
</tr>
<tr>
<td><code>&gt;=</code></td>
<td>大于或等于</td>
</tr>
<tr>
<td><code>==</code></td>
<td>等于，比较对象是否相等</td>
</tr>
<tr>
<td><code>!=</code></td>
<td>不等于</td>
</tr>
</tbody></table>
<h3>实例</h3>
<pre>
#!/usr/bin/python3

# 程序演示了 == 操作符
# 使用数字
print(5 == 6)
# 使用变量
x = 5
y = 8
print(x == y)
</pre>
<p>
以上实例输出结果：
</p>
<pre>
False
False
</pre>
<p>high_low.py文件演示了数字的比较运算：</p>
<pre>
#!/usr/bin/python3 

# 该实例演示了数字猜谜游戏
number = 7
guess = -1
print("数字猜谜游戏!")
while guess != number:
    guess = int(input("请输入你猜的数字："))

    if guess == number:
        print("恭喜，你猜对了！")
    elif guess &lt; number:
        print("猜的数字小了...")
    elif guess &gt; number:
        print("猜的数字大了...")
</pre>
<p>
执行以上脚本，实例输出结果如下：
</p>
<pre>
$ python3 high_low.py 
数字猜谜游戏!
请输入你猜的数字：1
猜的数字小了...
请输入你猜的数字：9
猜的数字大了...
请输入你猜的数字：7
恭喜，你猜对了！
</pre>
<hr>
<h2>if 嵌套</h2>
<p>
在嵌套 if 语句中，可以把 if...elif...else 结构放在另外一个 if...elif...else 结构中。
</p>
<pre>
if 表达式1:
    语句
    if 表达式2:
        语句
    elif 表达式3:
        语句
    else
        语句
elif 表达式4:
    语句
else:
    语句
</pre>
<h3>实例</h3>
<pre>
# !/usr/bin/python3

num=int(input("输入一个数字："))
if num%2==0:
    if num%3==0:
        print ("你输入的数字可以整除 2 和 3")
    else:
        print ("你输入的数字可以整除 2，但不能整除 3")
else:
    if num%3==0:
        print ("你输入的数字可以整除 3，但不能整除 2")
    else:
        print  ("你输入的数字不能整除 2 和 3")
</pre>
<p>将以上程序保存到 test_if.py 文件中，执行后输出结果为：</p>
<pre>
$ python3 test.py 
输入一个数字：6
你输入的数字可以整除 2 和 3
</pre>
</div></div><div data-role='page' id='loop.html'><div data-role='header'><h1>循环语句</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('function.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 循环语句</h1>
<p>本章节将为大家介绍Python循环语句的使用。</p>
<p>Python中的循环语句有 for 和 while。</p>
<p>Python循环语句的控制结构图如下所示：</p>
<p>
<img src="while_loop_1.png" />
</p>
<hr>
<h2>
while 循环
</h2>
<p>Python中while语句的一般形式：</p>
<pre>
while 判断条件：
    语句
</pre>
<p>
同样需要注意冒号和缩进。另外，在Python中没有do..while循环。
</p>
<p>以下实例使用了 while 来计算 1 到 100 的总和：</p>
<pre>
#!/usr/bin/env python3

n = 100

sum = 0
counter = 1
while counter &lt;= n:
    sum = sum + counter
    counter += 1

print("1 到 %d 之和为: %d" % (n,sum))
</pre>
<p>执行结果如下：</p>
<pre>
1 到 100 之和为: 5050
</pre>
<h3>无限循环</h3>
<p>我们可以通过设置条件表达式永远不为 false 来实现无限循环，实例如下：</p>
<pre>
#!/usr/bin/python3

var = 1
while var == 1 :  # 表达式永远为 true
   num = int(input("输入一个数字  :"))
   print ("你输入的数字是: ", num)

print ("Good bye!")
</pre>
<p>执行以上脚本，输出结果如下：</p>
<pre>
输入一个数字  :5
你输入的数字是:  5
输入一个数字  :
</pre>
<p>你可以使用 <b> CTRL+C</b> 来退出当前的无限循环。</p>
<p>无限循环在服务器上客户端的实时请求非常有用。</p>
<h3>while 循环使用 else 语句</h3><p>
在 while … else 在条件语句为 false 时执行 else 的语句块：</p>
<pre>
#!/usr/bin/python3

count = 0
while count &lt; 5:
   print (count, " 小于 5")
   count = count + 1
else:
   print (count, " 大于或等于 5")
</pre>
<p>执行以上脚本，输出结果如下：</p>
<pre>
0  小于 5
1  小于 5
2  小于 5
3  小于 5
4  小于 5
5  大于或等于 5
</pre><h3>
简单语句组</h3><p>
类似if语句的语法，如果你的while循环体中只有一条语句，你可以将该语句与while写在同一行中， 如下所示：</p>
<pre>
#!/usr/bin/python

flag = 1

while (flag): print ('欢迎访问菜鸟教程!')

print ("Good bye!")
</pre>
<p><strong>注意：</strong>以上的无限循环你可以使用 CTRL+C 来中断循环。</p>
<p>执行以上脚本，输出结果如下：</p>
<pre>
</pre>
<hr>
<h2>for 语句</h2>
<p>Python for循环可以遍历任何序列的项目，如一个列表或者一个字符串。</p>
<p>for循环的一般格式如下：</p>
<pre>
for &lt;variable&gt; in &lt;sequence&gt;:
    &lt;statements&gt;
else:
    &lt;statements&gt;
</pre>
<p>Python loop循环实例：</p>
<pre>
&gt;&gt;&gt; languages = ["C", "C++", "Perl", "Python"] 
&gt;&gt;&gt; for x in languages:
...     print x
... 
C
C++
Perl
Python
&gt;&gt;&gt; 
</pre>
<p>以下 for 实例中使用了 break 语句，break 语句用于跳出当前循环体：</p>
<pre>
#!/usr/bin/python3

sites = ["Baidu", "Google","Runoob","Taobao"]
for site in sites:
    if site == "Runoob":
        print("菜鸟教程!")
        break
    print("循环数据 " + site)
else:
    print("没有循环数据!")
print("完成循环!")
</pre>
<p>执行脚本后，在循环到 "Runoob"时会跳出循环体：</p>
<pre>
循环数据 Baidu
循环数据 Google
菜鸟教程!
完成循环!
</pre>
<hr>
<h2>
range()函数</h2>
<p>如果你需要遍历数字序列，可以使用内置range()函数。它会生成数列，例如:
</p>
<pre>
&gt;&gt;&gt; for i in range(5):
...     print(i)
...
0
1
2
3
4
</pre>
<p>你也可以使用range指定区间的值：</p>
<pre>
&gt;&gt;&gt; for i in range(5,9) :
    print(i)

    
5
6
7
8
&gt;&gt;&gt;
</pre> 
<p>
也可以使range以指定数字开始并指定不同的增量(甚至可以是负数，有时这也叫做'步长'): 
</p>
<pre>
&gt;&gt;&gt; for i in range(0, 10, 3) :
    print(i)

    
0
3
6
9
&gt;&gt;&gt; 
</pre>
<p>负数：</p>
<pre>
&gt;&gt;&gt; for i in range(-10, -100, -30) :
    print(i)

    
-10
-40
-70
&gt;&gt;&gt; 
</pre>
<p>您可以结合range()和len()函数以遍历一个序列的索引,如下所示:</p>
<pre>
&gt;&gt;&gt; a = ['Google', 'Baidu', 'Runoob', 'Taobao', 'QQ']
&gt;&gt;&gt; for i in range(len(a)):
...     print(i, a[i])
... 
0 Google
1 Baidu
2 Runoob
3 Taobao
4 QQ
&gt;&gt;&gt; 
</pre>
<p>还可以使用range()函数来创建一个列表：</p>
<pre>
&gt;&gt;&gt; list(range(5))
[0, 1, 2, 3, 4]
&gt;&gt;&gt;
</pre>
<hr>
<h2>
break和continue语句及循环中的else子句
</h2>
<p>break 语句可以跳出 for 和 while 的循环体。如果你从 for 或 while 循环中终止，任何对应的循环 else 块将不执行。
实例如下：
</p>

<pre>
#!/usr/bin/python3

for letter in 'Runoob':     # 第一个实例
   if letter == 'b':
      break
   print ('当前字母为 :', letter)
  
var = 10                    # 第二个实例
while var &gt; 0:              
   print ('当期变量值为 :', var)
   var = var -1
   if var == 5:
      break

print ("Good bye!")
</pre>
<p>执行以上脚本输出结果为：</p>
<pre>
当前字母为 : R
当前字母为 : u
当前字母为 : n
当前字母为 : o
当前字母为 : o
当期变量值为 : 10
当期变量值为 : 9
当期变量值为 : 8
当期变量值为 : 7
当期变量值为 : 6
Good bye!
</pre>

<p>continue语句被用来告诉Python跳过当前循环块中的剩余语句，然后继续进行下一轮循环。
</p>
<pre>
#!/usr/bin/python3

for letter in 'Runoob':     # 第一个实例
   if letter == 'o':        # 字母为 o 时跳过输出
      continue
   print ('当前字母 :', letter)

var = 10                    # 第二个实例
while var &gt; 0:              
   var = var -1
   if var == 5:             # 变量为 5 时跳过输出
      continue
   print ('当前变量值 :', var)
print ("Good bye!")
</pre>
<p>执行以上脚本输出结果为：</p>
<pre>
当前字母 : R
当前字母 : u
当前字母 : n
当前字母 : b
当前变量值 : 9
当前变量值 : 8
当前变量值 : 7
当前变量值 : 6
当前变量值 : 4
当前变量值 : 3
当前变量值 : 2
当前变量值 : 1
当前变量值 : 0
Good bye!
</pre>
<p>循环语句可以有 else 子句，它在穷尽列表(以for循环)或条件变为 false (以while循环)导致循环终止时被执行,但循环被break终止时不执行。
</p>
<p>
如下实例用于查询质数的循环例子:</p>
<pre>
#!/usr/bin/python3

for n in range(2, 10):
    for x in range(2, n):
        if n % x == 0:
            print(n, '等于', x, '*', n//x)
            break
    else:
        # 循环中没有找到元素
        print(n, ' 是质数')
</pre>
<p>执行以上脚本输出结果为：</p>
<pre>
2  是质数
3  是质数
4 等于 2 * 2
5  是质数
6 等于 2 * 3
7  是质数
8 等于 2 * 4
9 等于 3 * 3
</pre>


<hr>
<h2>pass 语句</h2>
<p>Python pass是空语句，是为了保持程序结构的完整性。</p>
<p>pass 不做任何事情，一般用做占位语句，如下实例</p>
<pre>
&gt;&gt;&gt; while True:
...     pass  # 等待键盘中断 (Ctrl+C)
</pre>
<p>最小的类:</p>
<pre>
&gt;&gt;&gt; class MyEmptyClass:
...     pass
</pre>
<p>以下实例在字母为 o 时 执行 pass 语句块:</p>
<pre>
#!/usr/bin/python3

for letter in 'Runoob': 
   if letter == 'o':
      pass
      print ('执行 pass 块')
   print ('当前字母 :', letter)

print ("Good bye!")
</pre>
<p>执行以上脚本输出结果为：</p>
<pre>
当前字母 : R
当前字母 : u
当前字母 : n
执行 pass 块
当前字母 : o
执行 pass 块
当前字母 : o
当前字母 : b
Good bye!
</pre>			
			
			</div></div><div data-role='page' id='function.html'><div data-role='header'><h1>函数</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('data-structure.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 函数</h1>
<p>函数是组织好的，可重复使用的，用来实现单一，或相关联功能的代码段。</p><p>函数能提高应用的模块性，和代码的重复利用率。你已经知道Python提供了许多内建函数，比如print()。但你也可以自己创建函数，这被叫做用户自定义函数。</p>
<hr>
<h2>定义一个函数</h2>

<p>你可以定义一个由自己想要功能的函数，以下是简单的规则：</p>
<ul>
<li>函数代码块以 <b>def</b> 关键词开头，后接函数标识符名称和圆括号 <b>()</b>。</li>

<li>任何传入参数和自变量必须放在圆括号中间，圆括号之间可以用于定义参数。</li>

<li>函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。</li>

<li>函数内容以冒号起始，并且缩进。</li>

<li><strong>return [表达式]</strong> 结束函数，选择性地返回一个值给调用方。不带表达式的return相当于返回 None。</li>
</ul><hr>
<h3>语法</h3>
<p>Python 定义函数使用 def 关键字，一般格式如下：</p>
<pre>
def 函数名（参数列表）:
    函数体
</pre>

<p>默认情况下，参数值和参数名称是按函数声明中定义的的顺序匹配起来的。</p>
<h3>实例</h3>
<p>让我们使用函数来输出"Hello World！"：</p>

<pre>
&gt;&gt;&gt; def hello() :
   print("Hello World!")

   
&gt;&gt;&gt; hello()
Hello World!
&gt;&gt;&gt; 
</pre>
<p>
更复杂点的应用，函数中带上参数变量:</p>
<pre>
#!/usr/bin/python3

# 计算面积函数
def area(width, height):
    return width * height
 
def print_welcome(name):
    print("Welcome", name)

print_welcome("Runoob")
w = 4
h = 5
print("width =", w, " height =", h, " area =", area(w, h))
</pre>
<p>以上实例输出结果：</p>
<pre>
Welcome Runoob
width = 4  height = 5  area = 20
</pre>
<hr>
<h2>函数调用</h2>
<p>定义一个函数：给了函数一个名称，指定了函数里包含的参数，和代码块结构。</p>

<p>这个函数的基本结构完成以后，你可以通过另一个函数调用执行，也可以直接从 Python 命令提示符执行。</p>

<p>如下实例调用了printme（）函数：</p>
<pre>
#!/usr/bin/python3
 
# 定义函数
def printme( str ):
   "打印任何传入的字符串"
   print (str);
   return;
 
# 调用函数
printme("我要调用用户自定义函数!");
printme("再次调用同一函数");
</pre>
<p>以上实例输出结果：</p>
<pre>
我要调用用户自定义函数!
再次调用同一函数
</pre><hr>
<h2>按值传递参数和按引用传递参数</h2>

<p>在 Python 中，所有参数（变量）都是按引用传递。如果你在函数里修改了参数，那么在调用这个函数的函数里，原始的参数也被改变了。例如：</p>
<pre>
#!/usr/bin/python3
 
# 可写函数说明
def changeme( mylist ):
   "修改传入的列表"
   mylist.append([1,2,3,4]);
   print ("函数内取值: ", mylist)
   return
 
# 调用changeme函数
mylist = [10,20,30];
changeme( mylist );
print ("函数外取值: ", mylist)
</pre>
<p>传入函数的和在末尾添加新内容的对象用的是同一个引用。故输出结果如下：</p>
<pre>
函数内取值:  [10, 20, 30, [1, 2, 3, 4]]
函数外取值:  [10, 20, 30, [1, 2, 3, 4]]
</pre><hr>
<h2>参数</h2>
<p>以下是调用函数时可使用的正式参数类型：</p>
<ul>
<li>必需参数</li>

<li>关键字参数</li>

<li>默认参数</li>

<li>不定长参数</li>
</ul>
<h3>必需参数</h3>

<p>必需参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。</p>

<p>调用printme()函数，你必须传入一个参数，不然会出现语法错误：</p>

<pre>
#!/usr/bin/python3
 
#可写函数说明
def printme( str ):
   "打印任何传入的字符串"
   print (str);
   return;
 
#调用printme函数
printme();
</pre>
<p>以上实例输出结果：</p>
<pre>
Traceback (most recent call last):
  File "test.py", line 10, in &lt;module&gt;
    printme();
TypeError: printme() missing 1 required positional argument: 'str'
</pre>
<h3>关键字参数</h3>

<p>关键字参数和函数调用关系紧密，函数调用使用关键字参数来确定传入的参数值。</p>
<p>使用关键字参数允许函数调用时参数的顺序与声明时不一致，因为 Python 解释器能够用参数名匹配参数值。</p>
<p>以下实例在函数 printme() 调用时使用参数名：</p>
<pre>
#!/usr/bin/python3
 
#可写函数说明
def printme( str ):
   "打印任何传入的字符串"
   print (str);
   return;
 
#调用printme函数
printme( str = "菜鸟教程");
</pre>
<p>以上实例输出结果：
</p>
<pre>
菜鸟教程
</pre>
<p>以下实例中演示了函数参数的使用不需要使用指定顺序：</p>
<pre>
#!/usr/bin/python3
 
#可写函数说明
def printinfo( name, age ):
   "打印任何传入的字符串"
   print ("名字: ", name);
   print ("年龄: ", age);
   return;
 
#调用printinfo函数
printinfo( age=50, name="runoob" );
</pre>
<p>以上实例输出结果：</p>
<pre>
名字:  runoob
年龄:  50
</pre>
<h3>默认参数</h3>

<p>调用函数时，如果没有传递参数，则会使用默认参数。以下实例中如果没有传入 age 参数，则使用默认值：</p>
<pre>
#!/usr/bin/python3
 
#可写函数说明
def printinfo( name, age = 35 ):
   "打印任何传入的字符串"
   print ("名字: ", name);
   print ("年龄: ", age);
   return;
 
#调用printinfo函数
printinfo( age=50, name="runoob" );
print ("------------------------")
printinfo( name="runoob" );
</pre>
<p>以上实例输出结果：</p>
<pre>
名字:  runoob
年龄:  50
------------------------
名字:  runoob
年龄:  35
</pre>
<h3>不定长参数</h3>

<p>你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数，和上述2种参数不同，声明时不会命名。基本语法如下：</p>
<pre>
def functionname([formal_args,] *var_args_tuple ):
   "函数_文档字符串"
   function_suite
   return [expression]
</pre>
<p>加了星号（*）的变量名会存放所有未命名的变量参数。如果在函数调用时没有指定参数，它就是一个空元组。我们也可以不向函数传递未命名的变量。如下实例：</p>
<pre>
#!/usr/bin/python3
 
# 可写函数说明
def printinfo( arg1, *vartuple ):
   "打印任何传入的参数"
   print ("输出: ")
   print (arg1)
   for var in vartuple:
      print (var)
   return;
 
# 调用printinfo 函数
printinfo( 10 );
printinfo( 70, 60, 50 );
</pre>
<p>以上实例输出结果：</p>
<pre>
输出:
10
输出:
70
60
50
</pre>


<hr><h2>匿名函数</h2>

<p>python 使用 lambda 来创建匿名函数。</p>
<p>所谓匿名，意即不再使用 def 语句这样标准的形式定义一个函数。</p>
<ul>

<li>lambda 只是一个表达式，函数体比 def 简单很多。
</li><li>
lambda的主体是一个表达式，而不是一个代码块。仅仅能在lambda表达式中封装有限的逻辑进去。
</li><li>lambda 函数拥有自己的命名空间，且不能访问自有参数列表之外或全局命名空间里的参数。</li>

<li>虽然lambda函数看起来只能写一行，却不等同于C或C++的内联函数，后者的目的是调用小函数时不占用栈内存从而增加运行效率。</li>
</ul>
<h3>语法</h3>

<p>lambda 函数的语法只包含一个语句，如下：</p>
<pre>
lambda [arg1 [,arg2,.....argn]]:expression
</pre>
<p>如下实例：</p>
<pre>
#!/usr/bin/python3
 
# 可写函数说明
sum = lambda arg1, arg2: arg1 + arg2;
 
# 调用sum函数
print ("相加后的值为 : ", sum( 10, 20 ))
print ("相加后的值为 : ", sum( 20, 20 ))
</pre>
<p>以上实例输出结果：</p>
<pre>
相加后的值为 :  30
相加后的值为 :  40
</pre>

<hr>
<h2>return语句</h2>

<p><b>return [表达式]</b> 语句用于退出函数，选择性地向调用方返回一个表达式。不带参数值的return语句返回None。之前的例子都没有示范如何返回数值，以下实例演示了 return 语句的用法：</p>
<pre>
#!/usr/bin/python3

# 可写函数说明
def sum( arg1, arg2 ):
   # 返回2个参数的和."
   total = arg1 + arg2
   print ("函数内 : ", total)
   return total;

# 调用sum函数
total = sum( 10, 20 );
print ("函数外 : ", total)
</pre>
<p>以上实例输出结果：</p>
<pre>
函数内 :  30
函数外 :  30
</pre><hr>
<h2>变量作用域</h2>

<p>Pyhton 中，程序的变量并不是在哪个位置都可以访问的，访问权限决定于这个变量是在哪里赋值的。</p>

<o>变量的作用域决定了在哪一部分程序可以访问哪个特定的变量名称。两种最基本的变量作用域如下：</p>
<ul>
<li>全局变量</li>

<li>局部变量</li>
</ul><hr>
<h2>全局变量和局部变量</h2>

<p>定义在函数内部的变量拥有一个局部作用域，定义在函数外的拥有全局作用域。</p>

<p>局部变量只能在其被声明的函数内部访问，而全局变量可以在整个程序范围内访问。调用函数时，所有在函数内声明的变量名称都将被加入到作用域中。如下实例：</p>
<pre>
#!/usr/bin/python3

total = 0; # 这是一个全局变量
# 可写函数说明
def sum( arg1, arg2 ):
    #返回2个参数的和."
    total = arg1 + arg2; # total在这里是局部变量.
    print ("函数内是局部变量 : ", total)
    return total;

#调用sum函数
sum( 10, 20 );
print ("函数外是全局变量 : ", total)
</pre>
<p>以上实例输出结果：</p>
<pre>
函数内是局部变量 :  30
函数外是全局变量 :  0
</pre>			
			
			</div></div><div data-role='page' id='data-structure.html'><div data-role='header'><h1>数据结构</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('module.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 数据结构</h1>
<p>本章节我们主要结合前面所学的知识点来介绍Python数据结构。</p>
<hr>
<h2>列表</h2>
<p>Python中列表是可变的，这是它区别于字符串和元组的最重要的特点，一句话概括即：列表可以修改，而字符串和元组不能。
</p>
<p>以下是 Python 中列表的方法：</p>
<table class="reference">
<tr>
<th>方法</th>
<th>描述</th>
</tr>
<tr>
<td>list.append(x)
</td>
<td>把一个元素添加到列表的结尾，相当于 a[len(a):] = [x]。
</td>
</tr>

<tr>
<td>list.extend(L)
</td>
<td>通过添加指定列表的所有元素来扩充列表，相当于 a[len(a):] = L。 
</td>
</tr>

<tr>
<td>list.insert(i, x)
</td>
<td>在指定位置插入一个元素。第一个参数是准备插入到其前面的那个元素的索引，例如 a.insert(0, x) 会插入到整个列表之前，而 a.insert(len(a), x) 相当于 a.append(x) 。
</td>
</tr>
<tr>
<td>list.remove(x)
</td>
<td>删除列表中值为 x 的第一个元素。如果没有这样的元素，就会返回一个错误。
</td>
</tr>

<tr>
<td>list.pop([i])
</td>
<td>从列表的指定位置删除元素，并将其返回。如果没有指定索引，a.pop()返回最后一个元素。元素随即从列表中被删除。（方法中 i 两边的方括号表示这个参数是可选的，而不是要求你输入一对方括号，你会经常在 Python 库参考手册中遇到这样的标记。）
</td>
</tr>

<tr>
<td>list.clear()
</td>
<td>移除列表中的所有项，等于del a[:]。
</td>
</tr>

<tr>
<td>list.index(x)
</td>
<td>返回列表中第一个值为 x 的元素的索引。如果没有匹配的元素就会返回一个错误。
</td>
</tr>

<tr>
<td>list.count(x)
</td>
<td>返回 x 在列表中出现的次数。
</td>
</tr>

<tr>
<td>list.sort()
</td>
<td>对列表中的元素进行排序。
</td>
</tr>

<tr>
<td>list.reverse()
</td>
<td>倒排列表中的元素。
</td>
</tr>

<tr>
<td>list.copy()
</td>
<td>返回列表的浅复制，等于a[:]。
</td>
</tr>
</table>
<p>下面示例演示了列表的大部分方法：</p>
<pre>
&gt;&gt;&gt; a = [66.25, 333, 333, 1, 1234.5]
&gt;&gt;&gt; print(a.count(333), a.count(66.25), a.count('x'))
2 1 0
&gt;&gt;&gt; a.insert(2, -1)
&gt;&gt;&gt; a.append(333)
&gt;&gt;&gt; a
[66.25, 333, -1, 333, 1, 1234.5, 333]
&gt;&gt;&gt; a.index(333)
1
&gt;&gt;&gt; a.remove(333)
&gt;&gt;&gt; a
[66.25, -1, 333, 1, 1234.5, 333]
&gt;&gt;&gt; a.reverse()
&gt;&gt;&gt; a
[333, 1234.5, 1, 333, -1, 66.25]
&gt;&gt;&gt; a.sort()
&gt;&gt;&gt; a
[-1, 1, 66.25, 333, 333, 1234.5]
</pre>
<p>注意：类似 insert, remove 或 sort 等修改列表的方法没有返回值。</p>
<hr>
<h2>将列表当做堆栈使用</h2>
<p>
列表方法使得列表可以很方便的作为一个堆栈来使用，堆栈作为特定的数据结构，最先进入的元素最后一个被释放（后进先出）。用 append() 方法可以把一个元素添加到堆栈顶。用不指定索引的 pop() 方法可以把一个元素从堆栈顶释放出来。例如： 
</p> 
<pre>
&gt;&gt;&gt; stack = [3, 4, 5]
&gt;&gt;&gt; stack.append(6)
&gt;&gt;&gt; stack.append(7)
&gt;&gt;&gt; stack
[3, 4, 5, 6, 7]
&gt;&gt;&gt; stack.pop()
7
&gt;&gt;&gt; stack
[3, 4, 5, 6]
&gt;&gt;&gt; stack.pop()
6
&gt;&gt;&gt; stack.pop()
5
&gt;&gt;&gt; stack
[3, 4]
</pre>
<hr>
<h2>将列表当作队列使用</h2>
<p>也可以把列表当做队列用，只是在队列里第一加入的元素，第一个取出来；但是拿列表用作这样的目的效率不高。在列表的最后添加或者弹出元素速度快，然而在列表里插入或者从头部弹出速度却不快（因为所有其他的元素都得一个一个地移动）。
</p>
<pre>
&gt;&gt;&gt; from collections import deque
&gt;&gt;&gt; queue = deque(["Eric", "John", "Michael"])
&gt;&gt;&gt; queue.append("Terry")           # Terry arrives
&gt;&gt;&gt; queue.append("Graham")          # Graham arrives
&gt;&gt;&gt; queue.popleft()                 # The first to arrive now leaves
'Eric'
&gt;&gt;&gt; queue.popleft()                 # The second to arrive now leaves
'John'
&gt;&gt;&gt; queue                           # Remaining queue in order of arrival
deque(['Michael', 'Terry', 'Graham'])
</pre>
<hr>
<h2>列表推导式</h2>
<p>列表推导式提供了从序列创建列表的简单途径。通常应用程序将一些操作应用于某个序列的每个元素，用其获得的结果作为生成新列表的元素，或者根据确定的判定条件创建子序列。 
</p>
<p>
每个列表推导式都在 for 之后跟一个表达式，然后有零到多个 for 或 if 子句。返回结果是一个根据表达从其后的 for 和 if 上下文环境中生成出来的列表。如果希望表达式推导出一个元组，就必须使用括号。

</p>
<p>这里我们将列表中每个数值乘三，获得一个新的列表：</p>
<pre>
&gt;&gt;&gt; vec = [2, 4, 6]
&gt;&gt;&gt; [3*x for x in vec]
[6, 12, 18]
</pre>
<p>现在我们玩一点小花样：</p>
<pre>
&gt;&gt;&gt; [[x, x**2] for x in vec]
[[2, 4], [4, 16], [6, 36]]
</pre>
<p>
这里我们对序列里每一个元素逐个调用某方法：
</p>
<pre>
&gt;&gt;&gt; freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']
&gt;&gt;&gt; [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
</pre>
<p>我们可以用 if 子句作为过滤器： </p>
<pre>
&gt;&gt;&gt; [3*x for x in vec if x &gt; 3]
[12, 18]
&gt;&gt;&gt; [3*x for x in vec if x &lt; 2]
[]
</pre>
<p>以下是一些关于循环和其它技巧的演示：</p>
<pre>
&gt;&gt;&gt; vec1 = [2, 4, 6]
&gt;&gt;&gt; vec2 = [4, 3, -9]
&gt;&gt;&gt; [x*y for x in vec1 for y in vec2]
[8, 6, -18, 16, 12, -36, 24, 18, -54]
&gt;&gt;&gt; [x+y for x in vec1 for y in vec2]
[6, 5, -7, 8, 7, -5, 10, 9, -3]
&gt;&gt;&gt; [vec1[i]*vec2[i] for i in range(len(vec1))]
[8, 12, -54]
</pre>
<p>列表推导式可以使用复杂表达式或嵌套函数：
</p>
<pre>
&gt;&gt;&gt; [str(round(355/113, i)) for i in range(1, 6)]
['3.1', '3.14', '3.142', '3.1416', '3.14159']
</pre>
<hr>
<h2>嵌套列表解析</h2>
<p>
Python的列表还可以嵌套。
</p>
<p>以下实例展示了3X4的矩阵列表：</p>
<pre>
&gt;&gt;&gt; matrix = [
...     [1, 2, 3, 4],
...     [5, 6, 7, 8],
...     [9, 10, 11, 12],
... ]
</pre>
<p>以下实例将3X4的矩阵列表转换为4X3列表：</p>
<pre>
&gt;&gt;&gt; [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
</pre>
<p>以下实例也可以使用以下方法来实现：</p>
<pre>
&gt;&gt;&gt; transposed = []
&gt;&gt;&gt; for i in range(4):
...     transposed.append([row[i] for row in matrix])
...
&gt;&gt;&gt; transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
</pre>
<p>另外一种实现方法：</p>
<pre>
&gt;&gt;&gt; transposed = []
&gt;&gt;&gt; for i in range(4):
...     # the following 3 lines implement the nested listcomp
...     transposed_row = []
...     for row in matrix:
...         transposed_row.append(row[i])
...     transposed.append(transposed_row)
...
&gt;&gt;&gt; transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
</pre>
<hr>
<h2>del 语句</h2>
<p>
使用 del 语句可以从一个列表中依索引而不是值来删除一个元素。这与使用 pop() 返回一个值不同。可以用 del 语句从列表中删除一个切割，或清空整个列表（我们以前介绍的方法是给该切割赋一个空列表）。例如：
</p>
<pre>
&gt;&gt;&gt; a = [-1, 1, 66.25, 333, 333, 1234.5]
&gt;&gt;&gt; del a[0]
&gt;&gt;&gt; a
[1, 66.25, 333, 333, 1234.5]
&gt;&gt;&gt; del a[2:4]
&gt;&gt;&gt; a
[1, 66.25, 1234.5]
&gt;&gt;&gt; del a[:]
&gt;&gt;&gt; a
[]
</pre>
<p>也可以用 del 删除实体变量： </p>
<pre>
&gt;&gt;&gt; del a
</pre>
<hr>
<h2> 元组和序列 </h2>
<p>
元组由若干逗号分隔的值组成，例如：
</p>
<pre>
&gt;&gt;&gt; t = 12345, 54321, 'hello!'
&gt;&gt;&gt; t[0]
12345
&gt;&gt;&gt; t
(12345, 54321, 'hello!')
&gt;&gt;&gt; # Tuples may be nested:
... u = t, (1, 2, 3, 4, 5)
&gt;&gt;&gt; u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
</pre>
<p>如你所见，元组在输出时总是有括号的，以便于正确表达嵌套结构。在输入时可能有或没有括号， 不过括号通常是必须的（如果元组是更大的表达式的一部分）。
</p>
<hr>
<h2>集合</h2>
<p>集合是一个无序不重复元素的集。基本功能包括关系测试和消除重复元素。</p>
<p>可以用大括号({})创建集合。注意：如果要创建一个空集合，你必须用 set() 而不是 {} ；后者创建一个空的字典，下一节我们会介绍这个数据结构。</p>
<p>以下是一个简单的演示：</p>
<pre>
&gt;&gt;&gt; basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
&gt;&gt;&gt; print(basket)                      # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
&gt;&gt;&gt; 'orange' in basket                 # fast membership testing
True
&gt;&gt;&gt; 'crabgrass' in basket
False

&gt;&gt;&gt; # Demonstrate set operations on unique letters from two words
...
&gt;&gt;&gt; a = set('abracadabra')
&gt;&gt;&gt; b = set('alacazam')
&gt;&gt;&gt; a                                  # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
&gt;&gt;&gt; a - b                              # letters in a but not in b
{'r', 'd', 'b'}
&gt;&gt;&gt; a | b                              # letters in either a or b
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
&gt;&gt;&gt; a &amp; b                              # letters in both a and b
{'a', 'c'}
&gt;&gt;&gt; a ^ b                              # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}&gt;&gt;&gt; basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
&gt;&gt;&gt; print(basket)                      # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
&gt;&gt;&gt; 'orange' in basket                 # fast membership testing
True
&gt;&gt;&gt; 'crabgrass' in basket
False

&gt;&gt;&gt; # Demonstrate set operations on unique letters from two words
...
&gt;&gt;&gt; a = set('abracadabra')
&gt;&gt;&gt; b = set('alacazam')
&gt;&gt;&gt; a                                  # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
&gt;&gt;&gt; a - b                              # letters in a but not in b
{'r', 'd', 'b'}
&gt;&gt;&gt; a | b                              # letters in either a or b
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
&gt;&gt;&gt; a &amp; b                              # letters in both a and b
{'a', 'c'}
&gt;&gt;&gt; a ^ b                              # letters in a or b but not both
{'r', 'd', 'b', 'm', 'z', 'l'}
</pre>
<p>集合也支持推导式：</p>
<pre>
&gt;&gt;&gt; a = {x for x in 'abracadabra' if x not in 'abc'}
&gt;&gt;&gt; a
{'r', 'd'}
</pre>
<hr>
<h2>字典</h2>
<p>另一个非常有用的 Python 内建数据类型是字典。</p>
<p>序列是以连续的整数为索引，与此不同的是，字典以关键字为索引，关键字可以是任意不可变类型，通常用字符串或数值。</p>
<p>理解字典的最佳方式是把它看做无序的键=>值对集合。在同一个字典之内，关键字必须是互不相同。</p>
<p>一对大括号创建一个空的字典：{}。</p>
<p>这是一个字典运用的简单例子： </p>
<pre>
&gt;&gt;&gt; tel = {'jack': 4098, 'sape': 4139}
&gt;&gt;&gt; tel['guido'] = 4127
&gt;&gt;&gt; tel
{'sape': 4139, 'guido': 4127, 'jack': 4098}
&gt;&gt;&gt; tel['jack']
4098
&gt;&gt;&gt; del tel['sape']
&gt;&gt;&gt; tel['irv'] = 4127
&gt;&gt;&gt; tel
{'guido': 4127, 'irv': 4127, 'jack': 4098}
&gt;&gt;&gt; list(tel.keys())
['irv', 'guido', 'jack']
&gt;&gt;&gt; sorted(tel.keys())
['guido', 'irv', 'jack']
&gt;&gt;&gt; 'guido' in tel
True
&gt;&gt;&gt; 'jack' not in tel
False
</pre>
<p>构造函数 dict() 直接从键值对元组列表中构建字典。如果有固定的模式，列表推导式指定特定的键值对：</p>
<pre>
&gt;&gt;&gt; dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'jack': 4098, 'guido': 4127}
</pre>
<p>此外，字典推导可以用来创建任意键和值的表达式词典：</p>
<pre>
&gt;&gt;&gt; {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}
</pre>
<p>如果关键字只是简单的字符串，使用关键字参数指定键值对有时候更方便： </p>
<pre>
&gt;&gt;&gt; dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'jack': 4098, 'guido': 4127}
</pre>
<hr>
<h2>遍历技巧</h2>
<p>
在字典中遍历时，关键字和对应的值可以使用 items() 方法同时解读出来：
</p>
<pre>
&gt;&gt;&gt; knights = {'gallahad': 'the pure', 'robin': 'the brave'}
&gt;&gt;&gt; for k, v in knights.items():
...     print(k, v)
...
gallahad the pure
robin the brave
</pre>
<p>在序列中遍历时，索引位置和对应值可以使用 enumerate() 函数同时得到：</p>
<pre>
&gt;&gt;&gt; for i, v in enumerate(['tic', 'tac', 'toe']):
...     print(i, v)
...
0 tic
1 tac
2 toe
</pre>
<p>同时遍历两个或更多的序列，可以使用 zip() 组合： </p>
<pre>
&gt;&gt;&gt; questions = ['name', 'quest', 'favorite color']
&gt;&gt;&gt; answers = ['lancelot', 'the holy grail', 'blue']
&gt;&gt;&gt; for q, a in zip(questions, answers):
...     print('What is your {0}?  It is {1}.'.format(q, a))
...
What is your name?  It is lancelot.
What is your quest?  It is the holy grail.
What is your favorite color?  It is blue.
</pre>
<p>要反向遍历一个序列，首先指定这个序列，然后调用 reversesd() 函数： </p>
<pre>
&gt;&gt;&gt; for i in reversed(range(1, 10, 2)):
...     print(i)
...
9
7
5
3
1
</pre>
<p>要按顺序遍历一个序列，使用 sorted() 函数返回一个已排序的序列，并不修改原值： </p>
<pre>
&gt;&gt;&gt; basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
&gt;&gt;&gt; for f in sorted(set(basket)):
...     print(f)
...
apple
banana
orange
pear
</pre>
<hr><h2>参阅文档</h2>
<ul>
<li><a target="_blank" href="/python3/python3-list.html">Python3 列表</a></li>
<li><a target="_blank" href="/python3/python3-tuple.html">Python3 元组</a></li>
<li><a target="_blank" href="/python3/python3-dictionary.html">Python3 字典</a></li>
</ul>			
			
			</div></div><div data-role='page' id='module.html'><div data-role='header'><h1>模块</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('inputoutput.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 模块</h1>
<p>在前面的几个章节中我们脚本上是用 python 解释器来编程，如果你从 Python 解释器退出再进入，那么你定义的所有的方法和变量就都消失了。</p>
<p>为此 Python 提供了一个办法，把这些定义存放在文件中，为一些脚本或者交互式的解释器实例使用，这个文件被称为模块。</p>
<p>模块是一个包含所有你定义的函数和变量的文件，其后缀名是.py。模块可以被别的程序引入，以使用该模块中的函数等功能。这也是使用 python 标准库的方法。</p><p>下面是一个使用 python 标准库中模块的例子。
</p>
<pre>
#!/usr/bin/python3
# 文件名: using_sys.py

import sys

print('命令行参数如下:')
for i in sys.argv:
   print(i)

print('\n\nPython 路径为：', sys.path, '\n')
</pre>
<p>执行结果如下所示：</p>
<pre>
$ python using_sys.py 参数1 参数2
命令行参数如下:
using_sys.py
参数1
参数2


Python 路径为： ['/root', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages'] 

</pre>
<ul>
<li>1、import sys 引入 python 标准库中的 sys.py 模块；这是引入某一模块的方法。</li><li>
2、sys.argv 是一个包含命令行参数的列表。</li><li>
3、sys.path 包含了一个 Python 解释器自动查找所需模块的路径的列表。
</li>
</ul>



<hr>
<h2>import 语句</h2>

<p>想使用 Python 源文件，只需在另一个源文件里执行 import 语句，语法如下：</p>
<pre>
import module1[, module2[,... moduleN]
</pre>
<p>
当解释器遇到 import 语句，如果模块在当前的搜索路径就会被导入。
</p><p>搜索路径是一个解释器会先进行搜索的所有目录的列表。如想要导入模块 support，需要把命令放在脚本的顶端：</p>
<p>support.py 文件代码为：</p>
<pre>
#!/usr/bin/python3
# Filename: support.py

def print_func( par ):
    print ("Hello : ", par)
    return
</pre>
<p>test.py 引入 support 模块：</p>
<pre>
#!/usr/bin/python3
# Filename: test.py
 
# 导入模块
import support
 
# 现在可以调用模块里包含的函数了
support.print_func("Runoob")
</pre>
<p>
以上实例输出结果：</p>
<pre>
$ python3 test.py 
Hello :  Runoob
</pre>
<p>一个模块只会被导入一次，不管你执行了多少次import。这样可以防止导入模块被一遍又一遍地执行。</p>

<p>当我们使用import语句的时候，Python解释器是怎样找到对应的文件的呢？</p>
<p>这就涉及到Python的搜索路径，搜索路径是由一系列目录名组成的，Python解释器就依次从这些目录中去寻找锁引入的模块。
</p>
<p>
这看起来很像环境变量，事实上，也可以通过定义环境变量的方式来确定搜索路径。</p>
<p>搜索路径是在Python编译或安装的时候确定的，安装新的库应该也会修改。搜索路径被存储在sys模块中的path变量，做一个简单的实验，在交互式解释器中，输入以下代码：
</p>
<pre>
&gt;&gt;&gt; import sys
&gt;&gt;&gt; sys.path
['', '/usr/lib/python3.4', '/usr/lib/python3.4/plat-x86_64-linux-gnu', '/usr/lib/python3.4/lib-dynload', '/usr/local/lib/python3.4/dist-packages', '/usr/lib/python3/dist-packages']
&gt;&gt;&gt; 
</pre>
<p>sys.path 输出是一个列表，其中第一项是空串''，代表当前目录（若是从一个脚本中打印出来的话，可以更清楚地看出是哪个目录），亦即我们执行python解释器的目录（对于脚本的话就是运行的脚本所在的目录）。
</p>
<p>
因此若像我一样在当前目录下存在与要引入模块同名的文件，就会把要引入的模块屏蔽掉。
</p>

<p>
了解了搜索路径的概念，就可以在脚本中修改sys.path来引入一些不在搜索路径中的模块。
</p>
<p>
现在，在解释器的当前目录或者 sys.path 中的一个目录里面来创建一个fibo.py的文件，代码如下：</p>
<pre>
# 斐波那契(fibonacci)数列模块

def fib(n):    # 定义到 n 的斐波那契数列
    a, b = 0, 1
    while b &lt; n:
        print(b, end=' ')
        a, b = b, a+b
    print()

def fib2(n): # 返回到 n 的斐波那契数列
    result = []
    a, b = 0, 1
    while b &lt; n:
        result.append(b)
        a, b = b, a+b
    return result
</pre>
<p>然后进入Python解释器，使用下面的命令导入这个模块：</p>
<pre>
&gt;&gt;&gt; import fibo
</pre>
<p>这样做并没有把直接定义在fibo中的函数名称写入到当前符号表里，只是把模块fibo的名字写到了那里。
</p><p>
可以使用模块名称来访问函数：
</p>
<pre>
&gt;&gt;&gt; fibo.fib(1000)
1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
&gt;&gt;&gt; fibo.fib2(100)
[1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
&gt;&gt;&gt; fibo.__name__
'fibo'
</pre>
<p>如果你打算经常使用一个函数，你可以把它赋给一个本地的名称：</p>
<pre>
&gt;&gt;&gt; fib = fibo.fib
&gt;&gt;&gt; fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
</pre>




<br><hr>
<h2>
from…import 语句</h2>

<p>Python的from语句让你从模块中导入一个指定的部分到当前命名空间中，语法如下：</p>
<pre>
from modname import name1[, name2[, ... nameN]]
</pre>
<p>例如，要导入模块 fibo 的 fib 函数，使用如下语句：</p>
<pre>
from fibo import fib
</pre>
<p>这个声明不会把整个fib模块导入到当前的命名空间中，它只会将fib里的fibonacci单个引入到执行这个声明的模块的全局符号表。</p>

<br><hr>
<h2>From…import* 语句</h2>
<p>
把一个模块的所有内容全都导入到当前的命名空间也是可行的，只需使用如下声明：
</p>
<pre>
from modname import *
</pre>
<p>这提供了一个简单的方法来导入一个模块中的所有项目。然而这种声明不该被过多地使用。
</p>














<hr>
<h2>深入模块</h2>
<p>模块除了方法定义，还可以包括可执行的代码。这些代码一般用来初始化这个模块。这些代码只有在第一次被导入时才会被执行。</p>
<p>每个模块有各自独立的符号表，在模块内部为所有的函数当作全局符号表来使用。

</p><p>所以，模块的作者可以放心大胆的在模块内部使用这些全局变量，而不用担心把其他用户的全局变量搞花。
</p><p>从另一个方面，当你确实知道你在做什么的话，你也可以通过 modname.itemname 这样的表示法来访问模块内的函数。 
</p>
<p>模块是可以导入其他模块的。在一个模块（或者脚本，或者其他地方）的最前面使用 import 来导入一个模块，当然这只是一个惯例，而不是强制的。被导入的模块的名称将被放入当前操作的模块的符号表中。
</p>
<p>还有一种导入的方法，可以使用 import 直接把模块内（函数，变量的）名称导入到当前操作模块。比如:</p>
<pre>
&gt;&gt;&gt; from fibo import fib, fib2
&gt;&gt;&gt; fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
</pre>
<p>这种导入的方法不会把被导入的模块的名称放在当前的字符表中（所以在这个例子里面，fibo 这个名称是没有定义的）。 
</p>
<p>这还有一种方法，可以一次性的把模块中的所有（函数，变量）名称都导入到当前模块的字符表: 
</p>
<pre>
&gt;&gt;&gt; from fibo import *
&gt;&gt;&gt; fib(500)
1 1 2 3 5 8 13 21 34 55 89 144 233 377
</pre>
<p>这将把所有的名字都导入进来，但是那些由单一下划线（_）开头的名字不在此例。大多数情况， Python程序员不使用这种方法，因为引入的其它来源的命名，很可能覆盖了已有的定义。 
</p>

<hr>
<h2>__name__属性</h2>
<p>
一个模块被另一个程序第一次引入时，其主程序将运行。如果我们想在模块被引入时，模块中的某一程序块不执行，我们可以用__name__属性来使该程序块仅在该模块自身运行时执行。
</p>
<pre>
#!/usr/bin/python3
# Filename: using_name.py

if __name__ == '__main__':
   print('程序自身在运行')
else:
   print('我来自另一模块')
</pre>
<p>
运行输出如下：
</p>
<pre>
$ python using_name.py
</pre>
<p>
程序自身在运行
</p>
<pre>
$ python
&gt;&gt;&gt; import using_name
我来自另一模块
&gt;&gt;&gt;
</pre>
<p><b>
说明：</b>
每个模块都有一个__name__属性，当其值是'__main__'时，表明该模块自身在运行，否则是被引入。</p>
<hr>
<h2>dir() 函数</h2>
<pre>
内置的函数 dir() 可以找到模块内定义的所有名称。以一个字符串列表的形式返回:
&lt;/p&gt;
&lt;pre&gt;
&gt;&gt;&gt; import fibo, sys
&gt;&gt;&gt; dir(fibo)
['__name__', 'fib', 'fib2']
&gt;&gt;&gt; dir(sys)  
['__displayhook__', '__doc__', '__excepthook__', '__loader__', '__name__',
 '__package__', '__stderr__', '__stdin__', '__stdout__',
 '_clear_type_cache', '_current_frames', '_debugmallocstats', '_getframe',
 '_home', '_mercurial', '_xoptions', 'abiflags', 'api_version', 'argv',
 'base_exec_prefix', 'base_prefix', 'builtin_module_names', 'byteorder',
 'call_tracing', 'callstats', 'copyright', 'displayhook',
 'dont_write_bytecode', 'exc_info', 'excepthook', 'exec_prefix',
 'executable', 'exit', 'flags', 'float_info', 'float_repr_style',
 'getcheckinterval', 'getdefaultencoding', 'getdlopenflags',
 'getfilesystemencoding', 'getobjects', 'getprofile', 'getrecursionlimit',
 'getrefcount', 'getsizeof', 'getswitchinterval', 'gettotalrefcount',
 'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
 'intern', 'maxsize', 'maxunicode', 'meta_path', 'modules', 'path',
 'path_hooks', 'path_importer_cache', 'platform', 'prefix', 'ps1',
 'setcheckinterval', 'setdlopenflags', 'setprofile', 'setrecursionlimit',
 'setswitchinterval', 'settrace', 'stderr', 'stdin', 'stdout',
 'thread_info', 'version', 'version_info', 'warnoptions']
</pre>
<p>如果没有给定参数，那么 dir() 函数会罗列出当前定义的所有名称:</p>
<pre>
&gt;&gt;&gt; a = [1, 2, 3, 4, 5]
&gt;&gt;&gt; import fibo
&gt;&gt;&gt; fib = fibo.fib
&gt;&gt;&gt; dir() # 得到一个当前模块中定义的属性列表
['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']
&gt;&gt;&gt; a = 5 # 建立一个新的变量 'a'
&gt;&gt;&gt; dir()
['__builtins__', '__doc__', '__name__', 'a', 'sys']
&gt;&gt;&gt;
&gt;&gt;&gt; del a # 删除变量名a
&gt;&gt;&gt;
&gt;&gt;&gt; dir()
['__builtins__', '__doc__', '__name__', 'sys']
&gt;&gt;&gt;
</pre>
<hr>
<h2>标准模块
</h2>
<p>
Python 本身带着一些标准的模块库，在 Python 库参考文档中将会介绍到（就是后面的"库参考文档"）。</p>
<p>有些模块直接被构建在解析器里，这些虽然不是一些语言内置的功能，但是他却能很高效的使用，甚至是系统级调用也没问题。</p>
<p>这些组件会根据不同的操作系统进行不同形式的配置，比如 winreg 这个模块就只会提供给 Windows 系统。</p>
<p>应该注意到这有一个特别的模块 sys ，它内置在每一个 Python 解析器中。变量 sys.ps1 和 sys.ps2 定义了主提示符和副提示符所对应的字符串:
</p>
<pre>
&gt;&gt;&gt; import sys
&gt;&gt;&gt; sys.ps1
'&gt;&gt;&gt; '
&gt;&gt;&gt; sys.ps2
'... '
&gt;&gt;&gt; sys.ps1 = 'C&gt; '
C&gt; print('Yuck!')
Yuck!
C&gt;
</pre>
<hr>
<h2>包</h2>
<p>
包是一种管理 Python 模块命名空间的形式，采用"点模块名称"。</p><p>
比如一个模块的名称是 A.B， 那么他表示一个包 A中的子模块 B 。</p><p>就好像使用模块的时候，你不用担心不同模块之间的全局变量相互影响一样，采用点模块名称这种形式也不用担心不同库之间的模块重名的情况。
</p><p>这样不同的作者都可以提供 NumPy 模块，或者是 Python 图形库。
</p>
<p>不妨假设你想设计一套统一处理声音文件和数据的模块（或者称之为一个"包"）。</p><p>现存很多种不同的音频文件格式（基本上都是通过后缀名区分的，例如： .wav，:file:.aiff，:file:.au，），所以你需要有一组不断增加的模块，用来在不同的格式之间转换。</p><p>
并且针对这些音频数据，还有很多不同的操作（比如混音，添加回声，增加均衡器功能，创建人造立体声效果），所你还需要一组怎么也写不完的模块来处理这些操作。</p><p>
这里给出了一种可能的包结构（在分层的文件系统中）: 

</p>
<pre>
sound/                          顶层包
      __init__.py               初始化 sound 包
      formats/                  文件格式转换子包
              __init__.py
              wavread.py
              wavwrite.py
              aiffread.py
              aiffwrite.py
              auread.py
              auwrite.py
              ...
      effects/                  声音效果子包
              __init__.py
              echo.py
              surround.py
              reverse.py
              ...
      filters/                  filters 子包
              __init__.py
              equalizer.py
              vocoder.py
              karaoke.py
              ...
</pre>
<p>
在导入一个包的时候，Python 会根据 sys.path 中的目录来寻找这个包中包含的子目录。 
</p><p>
目录只有包含一个叫做 __init__.py 的文件才会被认作是一个包，主要是为了避免一些滥俗的名字（比如叫做 string）不小心的影响搜索路径中的有效模块。</p><p>
最简单的情况，放一个空的 :file:__init__.py就可以了。当然这个文件中也可以包含一些初始化代码或者为（将在后面介绍的） __all__变量赋值。 
</p><p>
用户可以每次只导入一个包里面的特定模块，比如: </p>
<pre>
import sound.effects.echo
</pre>
<p>
这将会导入子模块:mod:song.effects.echo。 他必须使用全名去访问: </p>
<pre>
sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)
</pre>
<p>
还有一种导入子模块的方法是:  </p>
<pre>
from sound.effects import echo
</pre>
<p>
这同样会导入子模块:mod:echo，并且他不需要那些冗长的前缀，所以他可以这样使用: </p>
<pre>
echo.echofilter(input, output, delay=0.7, atten=4)
</pre>
<p>
还有一种变化就是直接导入一个函数或者变量:  </p>
<pre>
from sound.effects.echo import echofilter
</pre>
<p>
同样的，这种方法会导入子模块:mod:echo，并且可以直接使用他的:func:echofilter函数: </pre>
<p>
echofilter(input, output, delay=0.7, atten=4)
</pre>
<p>
注意当使用from package import item这种形式的时候，对应的item既可以是包里面的子模块（子包），或者包里面定义的其他名称，比如函数，类或者变量。</p><p>
import语法会首先把item当作一个包定义的名称，如果没找到，再试图按照一个模块去导入。如果还没找到，恭喜，一个:exc:ImportError 异常被抛出了。
</p>
<p>
反之，如果使用形如import item.subitem.subsubitem这种导入形式，除了最后一项，都必须是包，而最后一项则可以是模块或者是包，但是不可以是类，函数或者变量的名字。 
</p>
<hr>
<h2>
从一个包中导入* </h2>
<p>
设想一下，如果我们使用 from sound.effects import *会发生什么？ 
</p>
<p>Python 会进入文件系统，找到这个包里面所有的子模块，一个一个的把它们都导入进来。</p><p>
但是很不幸，这个方法在 Windows平台上工作的就不是非常好，因为Windows是一个大小写不区分的系统。</p>
<p>在这类平台上，没有人敢担保一个叫做 ECHO.py 的文件导入为模块:mod:echo还是:mod:Echo甚至:mod:ECHO。</p><p>
（例如，Windows 95就很讨厌的把每一个文件的首字母大写显示）而且 DOS 的 8+3 命名规则对长模块名称的处理会把问题搞得更纠结。
</p>
<p>
为了解决这个问题，只能烦劳包作者提供一个精确的包的索引了。</p><p>
导入语句遵循如下规则：如果包定义文件 __init__.py 存在一个叫做 __all__ 的列表变量，那么在使用 from package import * 的时候就把这个列表中的所有名字作为包内容导入。</p><p>

<p>作为包的作者，可别忘了在更新包之后保证 __all__ 也更新了啊。你说我就不这么做，我就不使用导入*这种用法，好吧，没问题，谁让你是老板呢。这里有一个例子，在:file:sounds/effects/__init__.py中包含如下代码:</p>
<p>
<pre>
__all__ = ["echo", "surround", "reverse"]
</pre>

<p>
这表示当你使用from sound.effects import *这种用法时，你只会导入包里面这三个子模块。 </p><p>

如果__all__真的而没有定义，那么使用from sound.effects import *这种语法的时候，就*不会*导入包:mod:sound.effects里的任何子模块。他只是把包:mod:sound.effects和它里面定义的所有内容导入进来（可能运行:file:__init__.py里定义的初始化代码）。 </p><p>
这会把 :file:__init__.py里面定义的所有名字导入进来。并且他不会破坏掉我们在这句话之前导入的所有明确指定的模块。看下这部分代码:  </p>
<pre>
import sound.effects.echo
import sound.effects.surround
from sound.effects import *
</pre>
<p>
这个例子中，在执行from...import前，包:mod:sound.effects中的echo和surround模块都被导入到当前的命名空间中了。（当然如果定义了__all__就更没问题了）
</p><p>
通常我们并不主张使用*这种方法来导入模块，因为这种方法经常会导致代码的可读性降低。不过这样倒的确是可以省去不少敲键的功夫，而且一些模块都设计成了只能通过特定的方法导入。</p><p>

记住，使用from Package import specific_submodule这种方法永远不会有错。事实上，这也是推荐的方法。除非是你要导入的子模块有可能和其他包的子模块重名。</p><p>
如果在结构中包是一个子包（比如这个例子中对于包:mod:sound来说），而你又想导入兄弟包（同级别的包）你就得使用导入绝对的路径来导入。比如，如果模块:mod:sound.filters.vocoder 要使用包:mod:sound.effects中的模块:mod:echo，你就要写成 from sound.effects import echo。</p>
<pre>
from . import echo
from .. import formats
from ..filters import equalizer
</pre>
<p>
无论是隐式的还是显式的相对导入都是从当前模块开始的。主模块的名字永远是"__main__"，一个Python应用程序的主模块，应当总是使用绝对路径引用。 
</p>
<p>
包还提供一个额外的属性，:attr:__path__。这是一个目录列表，里面每一个包含的目录都有为这个包服务的:file:__init__.py，你得在其他:file:__init__.py被执行前定义哦。可以修改这个变量，用来影响包含在包里面的模块和子包。 
</p>
<p>
这个功能并不常用，一般用来扩展包里面的模块。 </p>			
			
			</div></div><div data-role='page' id='inputoutput.html'><div data-role='header'><h1>输入和输出</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('errors-execptions.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 输入和输出</h1>

<p>在前面几个章节中，我们其实已经接触了 Python 的输入输出的功能。本章节我们将具体介绍 Python 的输入输出。</p>
<h2>

<hr>
<h2>输出格式美化</h2>
<p>
Python两种输出值的方式: 表达式语句和 print() 函数。
</p><p>第三种方式是使用文件对象的 write() 方法，标准输出文件可以用 sys.stdout 引用。</p>
</p>
<p>如果你希望输出的形式更加多样，可以使用 str.format() 函数来格式化输出值。</p>
<p>如果你希望将输出的值转成字符串，可以使用 repr() 或 str() 函数来实现。</p>
<ul><li>
<b>str()：</b> 函数返回一个用户易读的表达形式。 </li><li>
<b>repr()：</b> 产生一个解释器易读的表达形式。</li></ul>
<h3>
例如
</h3>

<pre>
&gt;&gt;&gt; s = 'Hello, Runoob'
&gt;&gt;&gt; str(s)
'Hello, Runoob'
&gt;&gt;&gt; repr(s)
"'Hello, Runoob'"
&gt;&gt;&gt; str(1/7)
'0.14285714285714285'
&gt;&gt;&gt; x = 10 * 3.25
&gt;&gt;&gt; y = 200 * 200
&gt;&gt;&gt; s = 'x 的值为： ' + repr(x) + ',  y 的值为：' + repr(y) + '...'
&gt;&gt;&gt; print(s)
x 的值为： 32.5,  y 的值为：40000...
&gt;&gt;&gt; #  repr() 函数可以转义字符串中的特殊字符
... hello = 'hello, runoob\n'
&gt;&gt;&gt; hellos = repr(hello)
&gt;&gt;&gt; print(hellos)
'hello, runoob\n'
&gt;&gt;&gt; # repr() 的参数可以是 Python 的任何对象
... repr((x, y, ('Google', 'Runoob')))
"(32.5, 40000, ('Google', 'Runoob'))"
</pre>
<p>
这里有两种方式输出一个平方与立方的表:
</p>
<pre>
&gt;&gt;&gt; for x in range(1, 11):
...     print(repr(x).rjust(2), repr(x*x).rjust(3), end=' ')
...     # 注意前一行 'end' 的使用
...     print(repr(x*x*x).rjust(4))
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000

&gt;&gt;&gt; for x in range(1, 11):
...     print('{0:2d} {1:3d} {2:4d}'.format(x, x*x, x*x*x))
...
 1   1    1
 2   4    8
 3   9   27
 4  16   64
 5  25  125
 6  36  216
 7  49  343
 8  64  512
 9  81  729
10 100 1000
</pre>
<p><b>注意：</b>在第一个例子中, 每列间的空格由 print() 添加。</p>
<p>
这个例子展示了字符串对象的 rjust() 方法, 它可以将字符串靠右, 并在左边填充空格。</p><p>
还有类似的方法, 如 ljust() 和 center()。 这些方法并不会写任何东西, 它们仅仅返回新的字符串。</p>
<p>
另一个方法 zfill(), 它会在数字的左边填充 0，如下所示：</p>
<pre>
&gt;&gt;&gt; '12'.zfill(5)
'00012'
&gt;&gt;&gt; '-3.14'.zfill(7)
'-003.14'
&gt;&gt;&gt; '3.14159265359'.zfill(5)
'3.14159265359'
</pre>
<p>str.format() 的基本使用如下:</p>
<pre>
&gt;&gt;&gt; print('{}网址： "{}!"'.format('菜鸟教程', 'www.runoob.com'))
菜鸟教程网址： "www.runoob.com!"
</pre>
<p>括号及其里面的字符 (称作格式化字段) 将会被 format() 中的参数替换。 </p>
<p>在括号中的数字用于指向传入对象在 format() 中的位置，如下所示：</p>
<pre>
&gt;&gt;&gt; print('{0} 和 {1}'.format('Google', 'Runoob'))
Google 和 Runoob
&gt;&gt;&gt; print('{1} 和 {0}'.format('Google', 'Runoob'))
Runoob 和 Google
</pre>
<p>
如果在 format() 中使用了关键字参数, 那么它们的值会指向使用该名字的参数。</p>
<pre>
&gt;&gt;&gt; print('{name}网址： {site}'.format(name='菜鸟教程', site='www.runoob.com'))
菜鸟教程网址： www.runoob.com
</pre>
<p>
位置及关键字参数可以任意的结合:
</p>
<pre>
&gt;&gt;&gt; print('站点列表 {0}, {1}, 和 {other}。'.format('Google', 'Runoob',
                                                       other='Taobao'))
站点列表 Google, Runoob, 和 Taobao。
</pre>
'!a' (使用 ascii()), '!s' (使用 str()) 和 '!r' (使用 repr()) 可以用于在格式化某个值之前对其进行转化:
<pre>
&gt;&gt;&gt; import math
&gt;&gt;&gt; print('常量 PI 的值近似为： {}。'.format(math.pi))
常量 PI 的值近似为： 3.141592653589793。
&gt;&gt;&gt; print('常量 PI 的值近似为： {!r}。'.format(math.pi))
常量 PI 的值近似为： 3.141592653589793。
</pre>
<p>可选项 ':' 和格式标识符可以跟着字段名。 这就允许对值进行更好的格式化。 下面的例子将 Pi 保留到小数点后三位：
</p>
<pre>
&gt;&gt;&gt; import math
&gt;&gt;&gt; print('常量 PI 的值近似为 {0:.3f}。'.format(math.pi))
常量 PI 的值近似为 3.142。
</pre>
<p>
在 ':' 后传入一个整数, 可以保证该域至少有这么多的宽度。 用于美化表格时很有用。
</p>
<pre>
&gt;&gt;&gt; table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
&gt;&gt;&gt; for name, number in table.items():
...     print('{0:10} ==&gt; {1:10d}'.format(name, number))
...
Runoob     ==&gt;          2
Taobao     ==&gt;          3
Google     ==&gt;          1
</pre>
<p>
如果你有一个很长的格式化字符串, 而你不想将它们分开, 那么在格式化时通过变量名而非位置会是很好的事情。
</p>
 <p>最简单的就是传入一个字典, 然后使用方括号 '[]' 来访问键值 :</p>
<pre>
&gt;&gt;&gt; table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
&gt;&gt;&gt; print('Runoob: {0[Runoob]:d}; Google: {0[Google]:d}; '
          'Taobao: {0[Taobao]:d}'.format(table))
Runoob: 2; Google: 1; Taobao: 3
</pre>
<p>
也可以通过在 table 变量前使用 '**' 来实现相同的功能：</p>
<pre>
&gt;&gt;&gt; table = {'Google': 1, 'Runoob': 2, 'Taobao': 3}
&gt;&gt;&gt; print('Runoob: {Runoob:d}; Google: {Google:d}; Taobao: {Taobao:d}'.format(**table))
Runoob: 2; Google: 1; Taobao: 3
</pre>


<hr>
<h2>旧式字符串格式化</h2>
<p>
% 操作符也可以实现字符串格式化。 它将左边的参数作为类似 sprintf() 式的格式化字符串, 而将右边的代入, 然后返回格式化后的字符串. 例如:
</p>
<pre>
&gt;&gt;&gt; import math
&gt;&gt;&gt; print('常量 PI 的值近似为：%5.3f。' % math.pi)
常量 PI 的值近似为：3.142。
</pre>
<p>
因为 str.format() 比较新的函数， 大多数的 Python 代码仍然使用 % 操作符。但是因为这种旧式的格式化最终会从该语言中移除, 应该更多的使用 str.format().
</p>
<hr>
<h2>读取键盘输入</h2>
<p>
Python提供了 input() 置函数从标准输入读入一行文本，默认的标准输入是键盘。</p>

<p>input 可以接收一个Python表达式作为输入，并将运算结果返回。
</p>
<pre>
#!/usr/bin/python3

str = input("请输入：");
print ("你输入的内容是: ", str)
</pre>
<p>
这会产生如下的对应着输入的结果：
</p>
<pre>
请输入：菜鸟教程
你输入的内容是:  菜鸟教程
</pre>


<hr>
<h2>读和写文件
</h2>
<p>
open() 将会返回一个 file 对象，基本语法格式如下: 
</p>
<pre>
open(filename, mode)
</pre>
<ul> <li>filename：filename 变量是一个包含了你要访问的文件名称的字符串值。</li> 
<li>mode：mode决定了打开文件的模式：只读，写入，追加等。所有可取值见如下的完全列表。这个参数是非强制的，默认文件访问模式为只读(r)。</li> </ul>
<p>不同模式打开文件的完全列表：</p>
<table class="reference"> <tbody><tr><th style="width:10%">模式</th><th>描述</th></tr> <tr><td>r</td><td>以只读方式打开文件。文件的指针将会放在文件的开头。这是默认模式。</td></tr> <tr><td>rb</td><td>以二进制格式打开一个文件用于只读。文件指针将会放在文件的开头。这是默认模式。</td></tr> <tr><td>r+</td><td>打开一个文件用于读写。文件指针将会放在文件的开头。</td></tr> <tr><td>rb+</td><td>以二进制格式打开一个文件用于读写。文件指针将会放在文件的开头。</td></tr> <tr><td>w</td><td>打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在，创建新文件。</td></tr> <tr><td>wb</td><td>以二进制格式打开一个文件只用于写入。如果该文件已存在则将其覆盖。如果该文件不存在，创建新文件。</td></tr> <tr><td>w+</td><td>打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在，创建新文件。</td></tr> <tr><td>wb+</td><td>以二进制格式打开一个文件用于读写。如果该文件已存在则将其覆盖。如果该文件不存在，创建新文件。</td></tr> <tr><td>a</td><td>打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。也就是说，新的内容将会被写入到已有内容之后。如果该文件不存在，创建新文件进行写入。</td></tr> <tr><td>ab</td><td>以二进制格式打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。也就是说，新的内容将会被写入到已有内容之后。如果该文件不存在，创建新文件进行写入。</td></tr> <tr><td>a+</td><td>打开一个文件用于读写。如果该文件已存在，文件指针将会放在文件的结尾。文件打开时会是追加模式。如果该文件不存在，创建新文件用于读写。</td></tr> <tr><td>ab+</td><td>以二进制格式打开一个文件用于追加。如果该文件已存在，文件指针将会放在文件的结尾。如果该文件不存在，创建新文件用于读写。</td></tr> </tbody></table>
<p>以下实例将字符串写入到文件 foo.txt 中：</p>
<pre>
#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo.txt", "w")

f.write( "Python 是一个非常好的语言。\n是的，的确非常好!!\n" )

# 关闭打开的文件
f.close()
</pre>

<ul>
<li>
第一个参数为要打开的文件名。 
</li>
<li>第二个参数描述文件如何使用的字符。 mode 可以是 'r' 如果文件只读, 'w' 只用于写 (如果存在同名文件则将被删除), 和 'a' 用于追加文件内容; 所写的任何数据都会被自动增加到末尾. 'r+' 同时用于读写。 mode 参数是可选的; 'r' 将是默认值。
</li>
</ul><p>
此时打开文件 foo.txt,显示如下：</p>
<pre>
$ cat /tmp/foo.txt 
Python 是一个非常好的语言。
是的，的确非常好!!
</pre>
<hr>
<h2>文件对象的方法</h2>
<p>
本节中剩下的例子假设已经创建了一个称为 f 的文件对象。
</p>
<h3>f.read()</h3>
<p>
为了读取一个文件的内容，调用 f.read(size), 这将读取一定数目的数据, 然后作为字符串或字节对象返回。</p>
<p>size 是一个可选的数字类型的参数。 当 size 被忽略了或者为负, 那么该文件的所有内容都将被读取并且返回。</p>
<p>以下实例假定文件 foo.txt 已存在（上面实例中已创建）：</p>
<pre>
#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo.txt", "r")

str = f.read()
print(str)

# 关闭打开的文件
f.close()
</pre>
<p>执行以上程序，输出结果为：</p>
<pre>
Python 是一个非常好的语言。
是的，的确非常好!!
</pre>
<h3>f.readline()</h3>
<p>
f.readline() 会从文件中读取单独的一行。换行符为 '\n'。f.readline() 如果返回一个空字符串, 说明已经已经读取到最后一行。</p>
<pre>
#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo.txt", "r")

str = f.readline()
print(str)

# 关闭打开的文件
f.close()
</pre>
<p>执行以上程序，输出结果为：</p>
<pre>
Python 是一个非常好的语言。
</pre>
<h3>f.readlines()</h3>
<p>
f.readlines() 将返回该文件中包含的所有行。
</p>
<p> 如果设置可选参数 sizehint, 则读取指定长度的字节, 并且将这些字节按行分割。
</p>
<pre>
#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo.txt", "r")

str = f.readlines()
print(str)

# 关闭打开的文件
f.close()
</pre>
<p>执行以上程序，输出结果为：</p>
<pre>
['Python 是一个非常好的语言。\n', '是的，的确非常好!!\n']
</pre>
<p>
另一种方式是迭代一个文件对象然后读取每行:
</p>
<pre>
#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo.txt", "r")

for line in f:
    print(line, end='')

# 关闭打开的文件
f.close()
</pre>
<p>执行以上程序，输出结果为：</p>
<pre>
Python 是一个非常好的语言。
是的，的确非常好!!
</pre>
<p>
这个方法很简单, 但是并没有提供一个很好的控制。 因为两者的处理机制不同, 最好不要混用。
</p>
<h3>f.write()</h3>
<p>
f.write(string) 将 string 写入到文件中, 然后返回写入的字符数。
</p>
<pre>
#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo.txt", "w")

num = f.write( "Python 是一个非常好的语言。\n是的，的确非常好!!\n" )
print(num)
# 关闭打开的文件
f.close()
</pre>
<p>执行以上程序，输出结果为：</p>
<pre>
29
</pre>
<p>
如果要写入一些不是字符串的东西, 那么将需要先进行转换:
</p>
<pre>
#!/usr/bin/python3

# 打开一个文件
f = open("/tmp/foo1.txt", "w")

value = ('www.runoob.com', 14)
s = str(value)
f.write(s)

# 关闭打开的文件
f.close()
</pre>
<p>执行以上程序，打开 foo1.txt 文件：</p>
<pre>
$ cat /tmp/foo1.txt 
('www.runoob.com', 14)
</pre>
<h3>f.tell()</h3>
<p>
f.tell() 返回文件对象当前所处的位置, 它是从文件开头开始算起的字节数。
</p>
<h3>f.seek()</h3>
<p>如果要改变文件当前的位置, 可以使用 f.seek(offset, from_what) 函数。</p>
<p>
from_what 的值, 如果是 0 表示开头, 如果是 1 表示当前位置, 2 表示文件的结尾，例如：</p>
</p>
<ul>
<li>
seek(x,0) ： 从起始位置即文件首行首字符开始移动 x 个字符</li><li>
seek(x,1) ： 表示从当前位置往后移动x个字符</li><li>
seek(-x,2)：表示从文件的结尾往前移动x个字符
</li></ul>
<p>
from_what 值为默认为0，即文件开头。下面给出一个完整的例子：</p>
<pre>
&gt;&gt;&gt; f = open('/tmp/foo.txt', 'rb+')
&gt;&gt;&gt; f.write(b'0123456789abcdef')
16
&gt;&gt;&gt; f.seek(5)     # 移动到文件的第六个字节
5
&gt;&gt;&gt; f.read(1)
b'5'
&gt;&gt;&gt; f.seek(-3, 2) # 移动到文件的倒数第三字节
13
&gt;&gt;&gt; f.read(1)
b'd'
</pre>
<p>
<h3>f.close()</h3>
在文本文件中 (那些打开文件的模式下没有 b 的), 只会相对于文件起始位置进行定位。</p>
<p>
当你处理完一个文件后, 调用 f.close() 来关闭文件并释放系统的资源，如果尝试再调用该文件，则会抛出异常。</p>
<pre>
&gt;&gt;&gt; f.close()
&gt;&gt;&gt; f.read()
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in ?
ValueError: I/O operation on closed file
&lt;pre&gt;
&lt;p&gt;
当处理一个文件对象时, 使用 with 关键字是非常好的方式。在结束后, 它会帮你正确的关闭文件。 而且写起来也比 try - finally 语句块要简短:&lt;/p&gt;
&lt;pre&gt;
&gt;&gt;&gt; with open('/tmp/foo.txt', 'r') as f:
...     read_data = f.read()
&gt;&gt;&gt; f.closed
True
</pre><p>
文件对象还有其他方法, 如 isatty() 和 trucate(), 但这些通常比较少用。</p>

<hr><h2>pickle 模块
</h2>
<p>
python的pickle模块实现了基本的数据序列和反序列化。</p>
<p>通过pickle模块的序列化操作我们能够将程序中运行的对象信息保存到文件中去，永久存储。</p>
<p>通过pickle模块的反序列化操作，我们能够从文件中创建上一次程序保存的对象。
</p>
<p>基本接口：
</p>
<pre>
pickle.dump(obj, file, [,protocol])
</pre>
<p>
有了 pickle 这个对象, 就能对 file 以读取的形式打开:
</p>
<pre>
x = pickle.load(file)
</pre>
<p><b>注解：</b>从 file 中读取一个字符串，并将它重构为原来的python对象。</p>
<p><b>file:</b> 类文件对象，有read()和readline()接口。</p>
<p>实例1：</p>
<pre>
#!/usr/bin/python3
import pickle

# 使用pickle模块将数据对象保存到文件
data1 = {'a': [1, 2.0, 3, 4+6j],
         'b': ('string', u'Unicode string'),
         'c': None}

selfref_list = [1, 2, 3]
selfref_list.append(selfref_list)

output = open('data.pkl', 'wb')

# Pickle dictionary using protocol 0.
pickle.dump(data1, output)

# Pickle the list using the highest protocol available.
pickle.dump(selfref_list, output, -1)

output.close()
</pre>
<p>实例2：</p>
<pre>
#!/usr/bin/python3
import pprint, pickle

#使用pickle模块从文件中重构python对象
pkl_file = open('data.pkl', 'rb')

data1 = pickle.load(pkl_file)
pprint.pprint(data1)

data2 = pickle.load(pkl_file)
pprint.pprint(data2)

pkl_file.close()
</pre>			
			
			</div></div><div data-role='page' id='errors-execptions.html'><div data-role='header'><h1>错误和异常</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('class.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 错误和异常</h1>
<p>作为Python初学者，在刚学习Python编程时，经常会看到一些报错信息，在前面我们没有提及，这章节我们会专门介绍。</p>
<p>Python有两种错误很容易辨认：语法错误和异常。</p>
<h2>语法错误</h2>
<p>Python 的语法错误或者称之为解析错，是初学者经常碰到的，如下实例</p>
<pre>
&gt;&gt;&gt; while True print('Hello world')
  File "&lt;stdin&gt;", line 1, in ?
    while True print('Hello world')
                   ^
SyntaxError: invalid syntax
</pre>
<p>这个例子中，函数 print() 被检查到有错误，是它前面缺少了一个冒号（:）。</p><p>
语法分析器指出了出错的一行，并且在最先找到的错误的位置标记了一个小小的箭头。</p>
<h2>异常</h2>
<p>即便Python程序的语法是正确的，在运行它的时候，也有可能发生错误。运行期检测到的错误被称为异常。</p>
<p>大多数的异常都不会被程序处理，都以错误信息的形式展现在这里:</p>
<pre>
&gt;&gt;&gt; 10 * (1/0)
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in ?
ZeroDivisionError: division by zero
&gt;&gt;&gt; 4 + spam*3
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in ?
NameError: name 'spam' is not defined
&gt;&gt;&gt; '2' + 2
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in ?
TypeError: Can't convert 'int' object to str implicitly
</pre>
<p>异常以不同的类型出现，这些类型都作为信息的一部分打印出来: 例子中的类型有 ZeroDivisionError，NameError 和 TypeError。
</p>
<p>错误信息的前面部分显示了异常发生的上下文，并以调用栈的形式显示具体信息。
</p>
<h2>异常处理</h2>
<p>以下例子中，让用户输入一个合法的整数，但是允许用户中断这个程序（使用 Control-C 或者操作系统提供的方法）。用户中断的信息会引发一个 KeyboardInterrupt 异常。
</p>
<pre>
&gt;&gt;&gt; while True:
        try:
            x = int(input("Please enter a number: "))
            break
        except ValueError:
            print("Oops!  That was no valid number.  Try again   ")
   
</pre>
<p>try语句按照如下方式工作；</p>
<ul>
<li>首先，执行try子句（在关键字try和关键字except之间的语句）</li>
<li>如果没有异常发生，忽略except子句，try子句执行后结束。</li>
<li>如果在执行try子句的过程中发生了异常，那么try子句余下的部分将被忽略。如果异常的类型和 except 之后的名称相符，那么对应的except子句将被执行。最后执行 try 语句之后的代码。</li>
<li>如果一个异常没有与任何的except匹配，那么这个异常将会传递给上层的try中。</li>

</ul>
<p>一个 try 语句可能包含多个except子句，分别来处理不同的特定的异常。最多只有一个分支会被执行。</p>
<p>处理程序将只针对对应的try子句中的异常进行处理，而不是其他的 try 的处理程序中的异常。</p><p>一个except子句可以同时处理多个异常，这些异常将被放在一个括号里成为一个元组，例如:
</p>
<pre>
    except (RuntimeError, TypeError, NameError):
        pass
</pre>
<p>最后一个except子句可以忽略异常的名称，它将被当作通配符使用。你可以使用这种方法打印一个错误信息，然后再次把异常抛出。</p>
<pre>
import sys

try:
    f = open('myfile.txt')
    s = f.readline()
    i = int(s.strip())
except OSError as err:
    print("OS error: {0}".format(err))
except ValueError:
    print("Could not convert data to an integer.")
except:
    print("Unexpected error:", sys.exc_info()[0])
    raise
</pre>
<p>try    except 语句还有一个可选的else子句，如果使用这个子句，那么必须放在所有的except子句之后。这个子句将在try子句没有发生任何异常的时候执行。例如:
</p>
<pre>
for arg in sys.argv[1:]:
    try:
        f = open(arg, 'r')
    except IOError:
        print('cannot open', arg)
    else:
        print(arg, 'has', len(f.readlines()), 'lines')
        f.close()
</pre>
<p>使用 else 子句比把所有的语句都放在 try 子句里面要好，这样可以避免一些意想不到的、而except又没有捕获的异常。</p>
<p>异常处理并不仅仅处理那些直接发生在try子句中的异常，而且还能处理子句中调用的函数（甚至间接调用的函数）里抛出的异常。例如:</p>
<pre>
&gt;&gt;&gt; def this_fails():
        x = 1/0
   
&gt;&gt;&gt; try:
        this_fails()
    except ZeroDivisionError as err:
        print('Handling run-time error:', err)
   
Handling run-time error: int division or modulo by zero
</pre>
<hr>
<h2>抛出异常</h2>
<p>
Python 使用 raise 语句抛出一个指定的异常。例如:</p>
<pre>
&gt;&gt;&gt; raise NameError('HiThere')
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in ?
NameError: HiThere
</pre>
<p>raise 唯一的一个参数指定了要被抛出的异常。它必须是一个异常的实例或者是异常的类（也就是 Exception 的子类）。</p>
<p>如果你只想知道这是否抛出了一个异常，并不想去处理它，那么一个简单的 raise 语句就可以再次把它抛出。</p>
<pre>
&gt;&gt;&gt; try:
        raise NameError('HiThere')
    except NameError:
        print('An exception flew by!')
        raise
   
An exception flew by!
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 2, in ?
NameError: HiThere
</pre>
<hr>
<h2>用户自定义异常</h2>
<p>你可以通过创建一个新的exception类来拥有自己的异常。异常应该继承自 Exception 类，或者直接继承，或者间接继承，例如:</p>
<pre>
&gt;&gt;&gt; class MyError(Exception):
        def __init__(self, value):
            self.value = value
        def __str__(self):
            return repr(self.value)
   
&gt;&gt;&gt; try:
        raise MyError(2*2)
    except MyError as e:
        print('My exception occurred, value:', e.value)
   
My exception occurred, value: 4
&gt;&gt;&gt; raise MyError('oops!')
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in ?
__main__.MyError: 'oops!'
</pre>
<p>在这个例子中，类 Exception 默认的 __init__() 被覆盖。</p>
<p异常的类可以像其他的类一样做任何事情，但是通常都会比较简单，只提供一些错误相关的属性，并且允许处理异常的代码方便的获取这些信息。</p>
<p>当创建一个模块有可能抛出多种不同的异常时，一种通常的做法是为这个包建立一个基础异常类，然后基于这个基础类为不同的错误情况创建不同的子类:</p>
<pre>
class Error(Exception):
    """Base class for exceptions in this module."""
    pass

class InputError(Error):
    """Exception raised for errors in the input.

    Attributes:
        expression -- input expression in which the error occurred
        message -- explanation of the error
    """

    def __init__(self, expression, message):
        self.expression = expression
        self.message = message

class TransitionError(Error):
    """Raised when an operation attempts a state transition that's not
    allowed.

    Attributes:
        previous -- state at beginning of transition
        next -- attempted new state
        message -- explanation of why the specific transition is not allowed
    """

    def __init__(self, previous, next, message):
        self.previous = previous
        self.next = next
        self.message = message
</pre>
<p>大多数的异常的名字都以"Error"结尾，就跟标准的异常命名一样。</p>
<hr>
<h2>定义清理行为</h2>
<p>try 语句还有另外一个可选的子句，它定义了无论在任何情况下都会执行的清理行为。 例如:</p>
<pre>
&gt;&gt;&gt; try:
        raise KeyboardInterrupt
	finally:
        print('Goodbye, world!')
   
Goodbye, world!
KeyboardInterrupt
</pre>
<p>以上例子洪不管try子句里面有没有发生异常，finally子句都会执行。</p>
<p>如果一个异常在 try 子句里（或者在 except 和 else 子句里）被抛出，而又没有任何的 except 把它截住，那么这个异常会在 finally 子句执行后再次被抛出。</p>
<p>下面是一个更加复杂的例子（在同一个 try 语句里包含 except 和 finally 子句）:</p>
<pre>
&gt;&gt;&gt; def divide(x, y):
        try:
            result = x / y
        except ZeroDivisionError:
            print("division by zero!")
        else:
            print("result is", result)
        finally:
            print("executing finally clause")
   
&gt;&gt;&gt; divide(2, 1)
result is 2.0
executing finally clause
&gt;&gt;&gt; divide(2, 0)
division by zero!
executing finally clause
&gt;&gt;&gt; divide("2", "1")
executing finally clause
Traceback (most recent call last):
  File "&lt;stdin&gt;", line 1, in ?
  File "&lt;stdin&gt;", line 3, in divide
TypeError: unsupported operand type(s) for /: 'str' and 'str'
</pre>
<hr>
<h2>预定义的清理行为</h2>
<p>一些对象定义了标准的清理行为，无论系统是否成功的使用了它，一旦不需要它了，那么这个标准的清理行为就会执行。</p>
<p>这面这个例子展示了尝试打开一个文件，然后把内容打印到屏幕上:
</p>
<pre>
for line in open("myfile.txt"):
    print(line, end="")
</pre>
<p>以上这段代码的问题是，当执行完毕后，文件会保持打开状态，并没有被关闭。</p>
<p>关键词 with 语句就可以保证诸如文件之类的对象在使用完之后一定会正确的执行他的清理方法:</p>
<pre>
with open("myfile.txt") as f:
    for line in f:
        print(line, end="")
</pre>
<p>以上这段代码执行完毕后，就算在处理过程中出问题了，文件 f 总是会关闭。
</p>			
			
			</div></div><div data-role='page' id='class.html'><div data-role='header'><h1>面向对象</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('stdlib.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 面向对象</h1>
<div class="tutintro">
<p>
Python从设计之初就已经是一门面向对象的语言，正因为如此，在Python中创建一个类和对象是很容易的。本章节我们将详细介绍Python的面向对象编程。
</p>
<p>
如果你以前没有接触过面向对象的编程语言，那你可能需要先了解一些面向对象语言的一些基本特征，在头脑里头形成一个基本的面向对象的概念，这样有助于你更容易的学习Python的面向对象编程。
</p>
<p>
接下来我们先来简单的了解下面向对象的一些基本特征。
</p>

</div>

<hr>
<h2>面向对象技术简介</h2>
<ul>
<li><strong>类(Class): </strong>用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。</li>
<li><strong>类变量：</strong>类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。</li>
<li><strong>数据成员：</strong>类变量或者实例变量用于处理类及其实例对象的相关的数据。</li>
<li><strong>方法重写：</strong>如果从父类继承的方法不能满足子类的需求，可以对其进行改写，这个过程叫方法的覆盖（override），也称为方法的重写。</li>
<li><strong>实例变量：</strong>定义在方法中的变量，只作用于当前实例的类。</li>
<li><strong>继承：</strong>即一个派生类（derived class）继承基类（base class）的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如，有这样一个设计：一个Dog类型的对象派生自Animal类，这是模拟"是一个（is-a）"关系（例图，Dog是一个Animal）。</li>
<li><strong>实例化：</strong>创建一个类的实例，类的具体对象。</li>
<li><strong>方法：</strong>类中定义的函数。</li>
<li><strong>对象：</strong>通过类定义的数据结构实例。对象包括两个数据成员（类变量和实例变量）和方法。</li>
</ul>
<p>和其它编程语言相比，Python 在尽可能不增加新的语法和语义的情况下加入了类机制。</p>
<p>Python中的类提供了面向对象编程的所有基本功能：类的继承机制允许多个基类，派生类可以覆盖基类中的任何方法，方法中可以调用基类中的同名方法。
<p>对象可以包含任意数量和类型的数据。
</p>
<h2>类定义</h2>
<p>语法格式如下：</p>
<pre>
class ClassName:
    &lt;statement-1&gt;
    .
    .
    .
    &lt;statement-N&gt;
</pre>
<p>类实例化后，可以使用其属性，实际上，创建一个类之后，可以通过类名访问其属性。</p>
<h2>类对象</h2>
<p>类对象支持两种操作：属性引用和实例化。</p>
<p>
属性引用使用和 Python 中所有的属性引用一样的标准语法：<b>obj.name</b>。</p><p>类对象创建后，类命名空间中所有的命名都是有效属性名。所以如果类定义是这样:</p>
<pre>
#!/usr/bin/python3

class MyClass:
    """一个简单的类实例"""
    i = 12345
    def f(self):
        return 'hello world'

# 实例化类
x = MyClass()

# 访问类的属性和方法
print("MyClass 类的属性 i 为：", x.i)
print("MyClass 类的方法 f 输出为：", x.f())
</pre>
<p>实例化类：</p>
<pre>
# 实例化类
x = MyClass()
# 访问类的属性和方法
</pre>

<p>以上创建了一个新的类实例并将该对象赋给局部变量 x，x 为空的对象。</p>
<p>执行以上程序输出结果为：</p>
<pre>
MyClass 类的属性 i 为： 12345
MyClass 类的方法 f 输出为： hello world
</pre>
<hr>
<p>很多类都倾向于将对象创建为有初始状态的。因此类可能会定义一个名为 __init__() 的特殊方法（构造方法），像下面这样：
</p>
<pre>
def __init__(self):
    self.data = []
</pre>
<p>类定义了 __init__() 方法的话，类的实例化操作会自动调用 __init__() 方法。所以在下例中，可以这样创建一个新的实例:</p>
<pre>
x = MyClass()
</pre>
<p>当然， __init__() 方法可以有参数，参数通过 __init__() 传递到类的实例化操作上。例如:
</p>
<pre>
&gt;&gt;&gt; class Complex:
...     def __init__(self, realpart, imagpart):
...         self.r = realpart
...         self.i = imagpart
...
&gt;&gt;&gt; x = Complex(3.0, -4.5)
&gt;&gt;&gt; x.r, x.i
(3.0, -4.5)
</pre>
<h2>类的方法</h2>
<p>
在类地内部，使用def关键字可以为类定义一个方法，与一般函数定义不同，类方法必须包含参数self,且为第一个参数:
</p>
<pre>
#!/usr/bin/python3

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

# 实例化类
p = people('runoob',10,30)
p.speak()
</pre>
<p>执行以上程序输出结果为：</p>
<pre>
runoob 说: 我 10 岁。
</pre>
<hr>
<h2>继承</h2>
<p>Python 同样支持类的继承，如果一种语言不支持继承就，类就没有什么意义。派生类的定义如下所示:</p>
<pre>
class DerivedClassName(BaseClassName1):
    &lt;statement-1&gt;
    .
    .
    .
    &lt;statement-N&gt;
</pre>
<p>需要注意圆括号中基类的顺序，若是基类中有相同的方法名，而在子类使用时未指定，python从左至右搜索
即方法在子类中未找到时，从左到右查找基类中是否包含方法。</p>
</p>
<p>
BaseClassName（示例中的基类名）必须与派生类定义在一个作用域内。除了类，还可以用表达式，基类定义在另一个模块中时这一点非常有用:
</p>
<pre>
class DerivedClassName(modname.BaseClassName):
</pre>
<h3>实例</h3>
<pre>
#!/usr/bin/python3

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

#单继承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #调用父类的构函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁了，我在读 %d 年级"%(self.name,self.age,self.grade))



s = student('ken',10,60,3)
s.speak()
</pre>
<p>执行以上程序输出结果为：</p>
<pre>
ken 说: 我 10 岁了，我在读 3 年级
</pre>
<hr>
<h2>多继承</h2>
<p>Python同样有限的支持多继承形式。多继承的类定义形如下例:</p>
<pre>
class DerivedClassName(Base1, Base2, Base3):
    &lt;statement-1&gt;
    .
    .
    .
    &lt;statement-N&gt;
</pre>
<p>需要注意圆括号中父类的顺序，若是父类中有相同的方法名，而在子类使用时未指定，python从左至右搜索
即方法在子类中未找到时，从左到右查找父类中是否包含方法。</p>
<pre>
#!/usr/bin/python3

#类定义
class people:
    #定义基本属性
    name = ''
    age = 0
    #定义私有属性,私有属性在类外部无法直接进行访问
    __weight = 0
    #定义构造方法
    def __init__(self,n,a,w):
        self.name = n
        self.age = a
        self.__weight = w
    def speak(self):
        print("%s 说: 我 %d 岁。" %(self.name,self.age))

#单继承示例
class student(people):
    grade = ''
    def __init__(self,n,a,w,g):
        #调用父类的构函
        people.__init__(self,n,a,w)
        self.grade = g
    #覆写父类的方法
    def speak(self):
        print("%s 说: 我 %d 岁了，我在读 %d 年级"%(self.name,self.age,self.grade))

#另一个类，多重继承之前的准备
class speaker():
    topic = ''
    name = ''
    def __init__(self,n,t):
        self.name = n
        self.topic = t
    def speak(self):
        print("我叫 %s，我是一个演说家，我演讲的主题是 %s"%(self.name,self.topic))

#多重继承
class sample(speaker,student):
    a =''
    def __init__(self,n,a,w,g,t):
        student.__init__(self,n,a,w,g)
        speaker.__init__(self,n,t)

test = sample("Tim",25,80,4,"Python")
test.speak()   #方法名同，默认调用的是在括号中排前地父类的方法
</pre>
<p>执行以上程序输出结果为：</p>
<pre>
我叫 Tim，我是一个演说家，我演讲的主题是 Python
</pre>
<hr>
<h2>
方法重写</h2><p>
如果你的父类方法的功能不能满足你的需求，你可以在子类重写你父类的方法，实例如下：</p>
<pre>
#!/usr/bin/python3

class Parent:        # 定义父类
   def myMethod(self):
      print ('调用父类方法')

class Child(Parent): # 定义子类
   def myMethod(self):
      print ('调用子类方法')

c = Child()          # 子类实例
c.myMethod()         # 子类调用重写方法
</pre>
<p>执行以上程序输出结果为：</p>
<pre>
调用子类方法
</pre>
<hr>
<h2>类属性与方法</h2>
<h3>类的私有属性</h3>
<p><strong>__private_attrs</strong>：两个下划线开头，声明该属性为私有，不能在类地外部被使用或直接访问。在类内部的方法中使用时 <strong>self.__private_attrs</strong>。</p>
<h3>类的方法</h3>
<p>在类地内部，使用def关键字可以为类定义一个方法，与一般函数定义不同，类方法必须包含参数self,且为第一个参数</p>


<h3>类的私有方法</h3>
<p>
<strong>__private_method</strong>：两个下划线开头，声明该方法为私有方法，不能在类地外部调用。在类的内部调用 <strong>slef.__private_methods</strong>。
</p>
<p>实例如下：</p>
<pre>
#!/usr/bin/python3

class JustCounter:
    __secretCount = 0  # 私有变量
    publicCount = 0    # 公开变量

    def count(self):
        self.__secretCount += 1
        self.publicCount += 1
        print (self.__secretCount)

counter = JustCounter()
counter.count()
counter.count()
print (counter.publicCount)
print (counter.__secretCount)  # 报错，实例不能访问私有变量
</pre>
<p>执行以上程序输出结果为：</p>
<pre>
1
2
2
Traceback (most recent call last):
  File "test.py", line 16, in &lt;module&gt;
    print (counter.__secretCount)  # 报错，实例不能访问私有变量
AttributeError: 'JustCounter' object has no attribute '__secretCount'
</pre>
<h3>
类的专有方法：</h3>
<ul>
	<li><strong>__init__ :</strong> 构造函数，在生成对象时调用</li>
	<li><strong>__del__ :</strong> 析构函数，释放对象时使用</li>
	<li><strong>__repr__ :</strong> 打印，转换</li>
	<li><strong>__setitem__ :</strong> 按照索引赋值</li>
	<li><strong>__getitem__:</strong> 按照索引获取值</li>
	<li><strong>__len__:</strong> 获得长度</li>
	<li><strong>__cmp__:</strong> 比较运算</li>
	<li><strong>__call__:</strong> 函数调用</li>
	<li><strong>__add__:</strong> 加运算</li>
	<li><strong>__sub__:</strong> 减运算</li>
	<li><strong>__mul__:</strong> 乘运算</li>
	<li><strong>__div__:</strong> 除运算</li>
	<li><strong>__mod__:</strong> 求余运算</li>
	<li><strong>__pow__:</strong> 称方</li>
</ul>
<h3>运算符重载</h3>
<p>Python同样支持运算符重载，我么可以对类的专有方法进行重载，实例如下：</p>
<pre>
#!/usr/bin/python3

class Vector:
   def __init__(self, a, b):
      self.a = a
      self.b = b

   def __str__(self):
      return 'Vector (%d, %d)' % (self.a, self.b)
   
   def __add__(self,other):
      return Vector(self.a + other.a, self.b + other.b)

v1 = Vector(2,10)
v2 = Vector(5,-2)
print (v1 + v2)
</pre>
<p>以上代码执行结果如下所示:</p>
<pre>
Vector(7,8)
</pre>
			
			
			</div></div><div data-role='page' id='stdlib.html'><div data-role='header'><h1>标准库概览</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('examples.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 标准库概览</h1>
<h2>操作系统接口</h2>
<p>os模块提供了不少与操作系统相关联的函数。</p>
<pre>
&gt;&gt;&gt; import os
&gt;&gt;&gt; os.getcwd()      # 返回当前的工作目录
'C:\\Python34'
&gt;&gt;&gt; os.chdir('/server/accesslogs')   # 修改当前的工作目录
&gt;&gt;&gt; os.system('mkdir today')   # 执行系统命令 mkdir 
0
</pre>
<p>建议使用 "import os" 风格而非 "from os import *"。这样可以保证随操作系统不同而有所变化的 os.open() 不会覆盖内置函数 open()。
</p>
<p>在使用 os 这样的大型模块时内置的 dir() 和 help() 函数非常有用:</p>
<pre>
&gt;&gt;&gt; import os
&gt;&gt;&gt; dir(os)
&lt;returns a list of all module functions&gt;
&gt;&gt;&gt; help(os)
&lt;returns an extensive manual page created from the module's docstrings&gt;
</pre>
<p>针对日常的文件和目录管理任务，:mod:shutil 模块提供了一个易于使用的高级接口:</p>
<pre>
&gt;&gt;&gt; import shutil
&gt;&gt;&gt; shutil.copyfile('data.db', 'archive.db')
&gt;&gt;&gt; shutil.move('/build/executables', 'installdir')
</pre>
<hr>
<h2> 文件通配符</h2>
<p>glob模块提供了一个函数用于从目录通配符搜索中生成文件列表:
</p>
<pre>
&gt;&gt;&gt; import glob
&gt;&gt;&gt; glob.glob('*.py')
['primes.py', 'random.py', 'quote.py']
</pre>
<hr>
<h2>命令行参数</h2>
<p>通用工具脚本经常调用命令行参数。这些命令行参数以链表形式存储于 sys 模块的 argv 变量。例如在命令行中执行 "python demo.py one two three" 后可以得到以下输出结果:
</p>
<pre>
&gt;&gt;&gt; import sys
&gt;&gt;&gt; print(sys.argv)
['demo.py', 'one', 'two', 'three']
</pre>
<hr>
<h2>错误输出重定向和程序终止</h2>
<p>sys 还有 stdin，stdout 和 stderr 属性，即使在 stdout 被重定向时，后者也可以用于显示警告和错误信息。</p>
<pre>
&gt;&gt;&gt; sys.stderr.write('Warning, log file not found starting a new one\n')
Warning, log file not found starting a new one
</pre>
<p>大多脚本的定向终止都使用 "sys.exit()"。</p>
<hr>
<h2>字符串正则匹配</h2>
<p>re模块为高级字符串处理提供了正则表达式工具。对于复杂的匹配和处理，正则表达式提供了简洁、优化的解决方案:
</p>
<pre>
&gt;&gt;&gt; import re
&gt;&gt;&gt; re.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')
['foot', 'fell', 'fastest']
&gt;&gt;&gt; re.sub(r'(\b[a-z]+) \1', r'\1', 'cat in the the hat')
'cat in the hat'
</pre>
<p>如果只需要简单的功能，应该首先考虑字符串方法，因为它们非常简单，易于阅读和调试:
</p>
<pre>
&gt;&gt;&gt; 'tea for too'.replace('too', 'two')
'tea for two'
</pre>
<hr>
<h2>数学 </h2>
<p>math模块为浮点运算提供了对底层C函数库的访问:
</p>
<pre>
&gt;&gt;&gt; import math
&gt;&gt;&gt; math.cos(math.pi / 4)
0.70710678118654757
&gt;&gt;&gt; math.log(1024, 2)
10.0
</pre>
<p>random提供了生成随机数的工具。</p>
<pre>
&gt;&gt;&gt; import random
&gt;&gt;&gt; random.choice(['apple', 'pear', 'banana'])
'apple'
&gt;&gt;&gt; random.sample(range(100), 10)   # sampling without replacement
[30, 83, 16, 4, 8, 81, 41, 50, 18, 33]
&gt;&gt;&gt; random.random()    # random float
0.17970987693706186
&gt;&gt;&gt; random.randrange(6)    # random integer chosen from range(6)
4
</pre>
<hr>
<h2>访问
互联网</h2>
<p>有几个模块用于访问互联网以及处理网络通信协议。其中最简单的两个是用于处理从 urls 接收的数据的 urllib.request 以及用于发送电子邮件的 smtplib:
</p>
<pre>
&gt;&gt;&gt; from urllib.request import urlopen
&gt;&gt;&gt; for line in urlopen('http://tycho.usno.navy.mil/cgi-bin/timer.pl'):
...     line = line.decode('utf-8')  # Decoding the binary data to text.
...     if 'EST' in line or 'EDT' in line:  # look for Eastern Time
...         print(line)

&lt;BR&gt;Nov. 25, 09:43:32 PM EST

&gt;&gt;&gt; import smtplib
&gt;&gt;&gt; server = smtplib.SMTP('localhost')
&gt;&gt;&gt; server.sendmail('soothsayer@example.org', 'jcaesar@example.org',
... """To: jcaesar@example.org
... From: soothsayer@example.org
...
... Beware the Ides of March.
... """)
&gt;&gt;&gt; server.quit()
</pre>
<p>注意第二个例子需要本地有一个在运行的邮件服务器。</p>
<hr>
<h2>日期和时间</h2>
<p>datetime模块为日期和时间处理同时提供了简单和复杂的方法。</p>
<p>支持日期和时间算法的同时，实现的重点放在更有效的处理和格式化输出。
</p><p>该模块还支持时区处理:
</p>
<pre>
&gt;&gt;&gt; # dates are easily constructed and formatted
&gt;&gt;&gt; from datetime import date
&gt;&gt;&gt; now = date.today()
&gt;&gt;&gt; now
datetime.date(2003, 12, 2)
&gt;&gt;&gt; now.strftime("%m-%d-%y. %d %b %Y is a %A on the %d day of %B.")
'12-02-03. 02 Dec 2003 is a Tuesday on the 02 day of December.'

&gt;&gt;&gt; # dates support calendar arithmetic
&gt;&gt;&gt; birthday = date(1964, 7, 31)
&gt;&gt;&gt; age = now - birthday
&gt;&gt;&gt; age.days
14368
</pre>
<hr>
<h2>数据压缩</h2>
<p>以下模块直接支持通用的数据打包和压缩格式：zlib，gzip，bz2，zipfile，以及 tarfile。</p>
<pre>
&gt;&gt;&gt; import zlib
&gt;&gt;&gt; s = b'witch which has which witches wrist watch'
&gt;&gt;&gt; len(s)
41
&gt;&gt;&gt; t = zlib.compress(s)
&gt;&gt;&gt; len(t)
37
&gt;&gt;&gt; zlib.decompress(t)
b'witch which has which witches wrist watch'
&gt;&gt;&gt; zlib.crc32(s)
226805979
</pre>
<hr>
<h2>性能度量</h2>
<p>有些用户对了解解决同一问题的不同方法之间的性能差异很感兴趣。Python 提供了一个度量工具，为这些问题提供了直接答案。</p>
<p>例如，使用元组封装和拆封来交换元素看起来要比使用传统的方法要诱人的多,timeit 证明了现代的方法更快一些。</p>
<pre>
&gt;&gt;&gt; from timeit import Timer
&gt;&gt;&gt; Timer('t=a; a=b; b=t', 'a=1; b=2').timeit()
0.57535828626024577
&gt;&gt;&gt; Timer('a,b = b,a', 'a=1; b=2').timeit()
0.54962537085770791
</pre>
<p>相对于 timeit 的细粒度，:mod:profile 和 pstats 模块提供了针对更大代码块的时间度量工具。</p>
<hr>
<h2>测试模块</h2>
<p>开发高质量软件的方法之一是为每一个函数开发测试代码，并且在开发过程中经常进行测试
</p>
<p>doctest模块提供了一个工具，扫描模块并根据程序中内嵌的文档字符串执行测试。
</p><p>测试构造如同简单的将它的输出结果剪切并粘贴到文档字符串中。
</p><p>通过用户提供的例子，它强化了文档，允许 doctest 模块确认代码的结果是否与文档一致:
</p>
<pre>
def average(values):
    """Computes the arithmetic mean of a list of numbers.

    &gt;&gt;&gt; print(average([20, 30, 70]))
    40.0
    """
    return sum(values) / len(values)

import doctest
doctest.testmod()   # 自动验证嵌入测试
</pre>
<p>unittest模块不像 doctest模块那么容易使用，不过它可以在一个独立的文件里提供一个更全面的测试集:
</p>
<pre>
import unittest

class TestStatisticalFunctions(unittest.TestCase):

    def test_average(self):
        self.assertEqual(average([20, 30, 70]), 40.0)
        self.assertEqual(round(average([1, 5, 7]), 1), 4.3)
        self.assertRaises(ZeroDivisionError, average, [])
        self.assertRaises(TypeError, average, 20, 30, 70)

unittest.main() # Calling from the command line invokes all tests
</pre>			
			
			</div></div><div data-role='page' id='examples.html'><div data-role='header'><h1>实例</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('reg-expressions.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 实例</h1>
<p>以下实例在 Python3.4.3 版本下测试通过：</p>
<ul>
<li><a href="/python3/python3-helloworld.html" title="python Hello World 实例"> Python Hello World 实例 </a></li>
<li><a href="python3-add-number.html" title="python Hello World 实例"> Python 数字求和 </a></li>
<li><a href="python3-square-root.html" title="python Hello World 实例"> Python 平方根 </a></li>
<li><a href="python3-quadratic-roots.html" target="_blank">Python 二次方程</a></li>
<li><a href="python3-area-triangle.html" target="_blank">Python 计算三角形的面积</a></li>
<li><a href="python3-random-number.html" target="_blank">Python 随机数生成</a></li>
<li><a href="python3-celsius-fahrenheit.html" target="_blank">Python 摄氏温度转华氏温度</a></li>

<li><a href="python3-swap-variables.html" target="_blank">Python 交换变量</a></li>
<li><a href="python3-if-example.html" target="_blank">Python if 语句</a></li>
<li><a href="python3-check-is-number.html" target="_blank">Python 判断字符串是否为数字</a></li>
<li><a href="python3-odd-even.html" target="_blank">Python 判断奇数偶数</a></li>
<li><a href="python3-leap-year.html" target="_blank">Python 判断闰年</a></li>
<li><a href="python3-largest-number.html" target="_blank">Python 获取最大值函数</a></li>
<li><a href="python3-prime-number.html" target="_blank">Python 质数判断</a></li>
<li><a href="python3-factorial.html" target="_blank">Python 阶乘实例</a></li>
<li><a href="python3-99-table.html" target="_blank">Python 九九乘法表</a></li>
<li><a href="python3-fibonacci-sequence.html" target="_blank">Python 斐波那契数列</a></li>
<li><a href="python3-armstrong-number.html" target="_blank">Python 阿姆斯特朗数</a></li>
<li><a href="python3-conversion-binary-octal-hexadecimal.html" target="_blank">Python 十进制转二进制、八进制、十六进制</a></li>
<li><a href="python3-ascii-character.html" target="_blank">Python ASCII码与字符相互转换</a></li>
<li><a href="python3-hcf.html" target="_blank">Python 最大公约数算法</a></li>
<li><a href="python3-lcm.html" target="_blank">Python 最小公倍数算法</a></li>
<li><a href="python3-calculator.html" target="_blank">Python 简单计算器实现</a></li>
<li><a href="python3-calendar.html" target="_blank">Python 生成日历</a></li>
<li><a href="python3-fibonacci-recursion.html" target="_blank">Python 使用递归斐波那契数列</a></li>
<li><a href="python3-file-io.html" target="_blank">Python 文件 IO</a></li>
<li><a href="python3-check-string.html" target="_blank">Python 字符串判断</a></li>
<li><a href="python3-upper-lower.html" target="_blank">Python 字符串大小写转换</a></li>
<li><a href="python3-month-days.html" target="_blank">Python 计算每个月天数</a></li>
<li><a href="python3-get-yesterday.html" target="_blank">Python 获取昨天日期</a></li>
<li><a href="python3-list-operator.html" target="_blank">Python list 常用操作</a></li>
</ul>			
			
			</div></div><div data-role='page' id='reg-expressions.html'><div data-role='header'><h1>正则表达式</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('cgi-programming.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 正则表达式</h1>
<p>正则表达式是一个特殊的字符序列，它能帮助你方便的检查一个字符串是否与某种模式匹配。</p><p>Python 自1.5版本起增加了re 模块，它提供 Perl 风格的正则表达式模式。</p>


<p>re 模块使 Python 语言拥有全部的正则表达式功能。 </p>
<p>compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。 </p>
<p>re 模块也提供了与这些方法功能完全一致的函数，这些函数使用一个模式字符串做为它们的第一个参数。</p>
<p>本章节主要介绍Python中常用的正则表达式处理函数。</p>
<hr><h2>re.match函数</h2>
<p>re.match 尝试从字符串的起始位置匹配一个模式，如果不是起始位置匹配成功的话，match()就返回none。</p>
<p><strong>函数语法</strong>：</p>
<pre>
re.match(pattern, string, flags=0)
</pre>
<p>函数参数说明：</p>
<table class="reference">
<tbody><tr>
<th style="width:30%">参数</th><th>描述</th>
</tr>
<tr><td>pattern</td><td>匹配的正则表达式</td></tr>
<tr><td>string</td><td>要匹配的字符串。</td></tr>
<tr><td>flags</td><td>标志位，用于控制正则表达式的匹配方式，如：是否区分大小写，多行匹配等等。</td></tr>
</tbody></table>
<p>匹配成功re.match方法返回一个匹配的对象，否则返回None。</p>
<p>我们可以使用group(num) 或  groups() 匹配对象函数来获取匹配表达式。</p>
<table class="reference">
<tbody><tr>
<th style="width:30%">匹配对象方法</th><th>描述</th>
</tr>
<tr><td>group(num=0)</td><td>匹配的整个表达式的字符串，group() 可以一次输入多个组号，在这种情况下它将返回一个包含那些组所对应值的元组。</td></tr>
<tr><td>groups()</td><td>返回一个包含所有小组字符串的元组，从 1 到 所含的小组号。</td></tr>
</tbody></table>
<p>实例 1：</p>
<pre>
#!/usr/bin/python
# -*- coding: UTF-8 -*- 

import re
print(re.match('www', 'www.runoob.com').span())  # 在起始位置匹配
print(re.match('com', 'www.runoob.com'))         # 不在起始位置匹配
</pre>
<p>以上实例运行输出结果为：</p>
<pre>
(0, 3)
None
</pre>
<p>实例 2：</p>
<pre>
#!/usr/bin/python3
import re

line = "Cats are smarter than dogs"

matchObj = re.match( r'(.*) are (.*?) .*', line, re.M|re.I)

if matchObj:
   print ("matchObj.group() : ", matchObj.group())
   print ("matchObj.group(1) : ", matchObj.group(1))
   print ("matchObj.group(2) : ", matchObj.group(2))
else:
   print ("No match!!")
</pre>
<p>以上实例执行结果如下：</p>
<pre>
matchObj.group() :  Cats are smarter than dogs
matchObj.group(1) :  Cats
matchObj.group(2) :  smarter
</pre>
<hr><h2>re.search方法</h2>
<p>re.search 扫描整个字符串并返回第一个成功的匹配。</p>
<p>函数语法：</p>
<pre>
re.search(pattern, string, flags=0)
</pre>
<p>函数参数说明：</p>
<table class="reference">
<tbody><tr>
<th style="width:30%">参数</th><th>描述</th>
</tr>
<tr><td>pattern</td><td>匹配的正则表达式</td></tr>
<tr><td>string</td><td>要匹配的字符串。</td></tr>
<tr><td>flags</td><td>标志位，用于控制正则表达式的匹配方式，如：是否区分大小写，多行匹配等等。</td></tr>
</tbody></table>
<p>匹配成功re.search方法返回一个匹配的对象，否则返回None。</p>
<p>我们可以使用group(num) 或  groups() 匹配对象函数来获取匹配表达式。</p>
<table class="reference">
<tbody><tr>
<th style="width:30%">匹配对象方法</th><th>描述</th>
</tr>
<tr><td>group(num=0)</td><td>匹配的整个表达式的字符串，group() 可以一次输入多个组号，在这种情况下它将返回一个包含那些组所对应值的元组。</td></tr>
<tr><td>groups()</td><td>返回一个包含所有小组字符串的元组，从 1 到 所含的小组号。</td></tr>
</tbody></table>
<p>实例 1：</p>
<pre>
#!/usr/bin/python3

import re

print(re.search('www', 'www.runoob.com').span())  # 在起始位置匹配
print(re.search('com', 'www.runoob.com').span())         # 不在起始位置匹配
</pre>
<p>以上实例运行输出结果为：</p>
<pre>
(0, 3)
(11, 14)
</pre>
<p>实例 2：</p>
<pre>
#!/usr/bin/python3

import re

line = "Cats are smarter than dogs";

searchObj = re.search( r'(.*) are (.*?) .*', line, re.M|re.I)

if searchObj:
   print ("searchObj.group() : ", searchObj.group())
   print ("searchObj.group(1) : ", searchObj.group(1))
   print ("searchObj.group(2) : ", searchObj.group(2))
else:
   print ("Nothing found!!")
</pre>
以上实例执行结果如下：
<pre>
searchObj.group() :  Cats are smarter than dogs
searchObj.group(1) :  Cats
searchObj.group(2) :  smarter
</pre>
<hr><h2>re.match与re.search的区别</h2>
<p>re.match只匹配字符串的开始，如果字符串开始不符合正则表达式，则匹配失败，函数返回None；而re.search匹配整个字符串，直到找到一个匹配。</p>
<p>实例：</p>
<pre>
#!/usr/bin/python3

import re

line = "Cats are smarter than dogs";

matchObj = re.match( r'dogs', line, re.M|re.I)
if matchObj:
   print ("match --&gt; matchObj.group() : ", matchObj.group())
else:
   print ("No match!!")

matchObj = re.search( r'dogs', line, re.M|re.I)
if matchObj:
   print ("search --&gt; matchObj.group() : ", matchObj.group())
else:
   print ("No match!!")
</pre>
以上实例运行结果如下：
<pre>
No match!!
search --&gt; matchObj.group() :  dogs
</pre>

<hr><h2>检索和替换</h2>
<p>Python 的re模块提供了re.sub用于替换字符串中的匹配项。</p>
<p>语法：</p>
<pre>
re.sub(pattern, repl, string, max=0)
</pre>
<p>返回的字符串是在字符串中用 RE 最左边不重复的匹配来替换。如果模式没有发现，字符将被没有改变地返回。</p>


<p>可选参数 count 是模式匹配后替换的最大次数；count 必须是非负整数。缺省值是 0 表示替换所有的匹配。</p>
<p>实例：</p>
<pre>
#!/usr/bin/python3
import re

phone = "2004-959-559 # 这是一个电话号码"

# 删除注释
num = re.sub(r'#.*$', "", phone)
print ("电话号码 : ", num)

# 移除非数字的内容
num = re.sub(r'\D', "", phone)
print ("电话号码 : ", num)
</pre>
以上实例执行结果如下：
<pre>
电话号码 :  2004-959-559 
电话号码 :  2004959559
</pre>
<hr>
<h2>正则表达式修饰符 - 可选标志</h2>
<p>正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志：</p>
<table class="reference">
<tbody><tr><th style="width:25%">修饰符</th><th>描述</th></tr>
<tr><td>re.I</td><td>使匹配对大小写不敏感</td></tr>
<tr><td>re.L</td><td>做本地化识别（locale-aware）匹配</td></tr>
<tr><td>re.M</td><td>多行匹配，影响 ^ 和 $</td></tr>
<tr><td>re.S</td><td>使 . 匹配包括换行在内的所有字符</td></tr>
<tr><td>re.U</td><td>根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.</td></tr>
<tr><td>re.X</td><td>该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。</td></tr>
</tbody></table>
<hr>
<h2>正则表达式模式</h2>
<p>模式字符串使用特殊的语法来表示一个正则表达式：</p>

<p>字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。</p>

<p>多数字母和数字前加一个反斜杠时会拥有不同的含义。</p>

<p>标点符号只有被转义时才匹配自身，否则它们表示特殊的含义。</p>

<p>反斜杠本身需要使用反斜杠转义。</p>

<p>由于正则表达式通常都包含反斜杠，所以你最好使用原始字符串来表示它们。模式元素(如 r'/t'，等价于'//t')匹配相应的特殊字符。</p>
<p>下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数，某些模式元素的含义会改变。</p>
<table class="reference">
<tbody><tr><th style="width:25%">模式</th><th>描述</th></tr>
<tr><td>^</td><td>匹配字符串的开头</td></tr>
<tr><td>$</td><td>匹配字符串的末尾。</td></tr>
<tr><td>.</td><td>匹配任意字符，除了换行符，当re.DOTALL标记被指定时，则可以匹配包括换行符的任意字符。</td></tr>
<tr><td>[...]</td><td>用来表示一组字符,单独列出：[amk] 匹配 'a'，'m'或'k'</td></tr>
<tr><td>[^...]</td><td>不在[]中的字符：[^abc] 匹配除了a,b,c之外的字符。</td></tr>
<tr><td>re*</td><td>匹配0个或多个的表达式。</td></tr>
<tr><td>re+</td><td>匹配1个或多个的表达式。</td></tr>
<tr><td>re?</td><td>   匹配0个或1个由前面的正则表达式定义的片段，非贪婪方式</td></tr>
<tr><td>re{ n}</td><td></td></tr>
<tr><td>re{ n,}</td><td>精确匹配n个前面表达式。</td></tr>
<tr><td>re{ n, m}</td><td>匹配 n 到 m 次由前面的正则表达式定义的片段，贪婪方式</td></tr>
<tr><td>a| b</td><td>匹配a或b</td></tr>
<tr><td>(re)</td><td>G匹配括号内的表达式，也表示一个组</td></tr>
<tr><td>(?imx)</td><td>正则表达式包含三种可选标志：i, m, 或 x 。只影响括号中的区域。</td></tr>
<tr><td>(?-imx)</td><td>正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域。</td></tr>
<tr><td>(?: re)</td><td> 类似 (...), 但是不表示一个组</td></tr>
<tr><td>(?imx: re)</td><td>在括号中使用i, m, 或 x 可选标志</td></tr>
<tr><td>(?-imx: re)</td><td>在括号中不使用i, m, 或 x 可选标志</td></tr>
<tr><td>(?#...)</td><td>注释.</td></tr>
<tr><td>(?= re)</td><td>前向肯定界定符。如果所含正则表达式，以 ... 表示，在当前位置成功匹配时成功，否则失败。但一旦所含表达式已经尝试，匹配引擎根本没有提高；模式的剩余部分还要尝试界定符的右边。</td></tr>
<tr><td>(?! re)</td><td>前向否定界定符。与肯定界定符相反；当所含表达式不能在字符串当前位置匹配时成功</td></tr>
<tr><td>(?&gt; re)</td><td>匹配的独立模式，省去回溯。</td></tr>
<tr><td>\w</td><td> 匹配字母数字</td></tr>
<tr><td>\W</td><td>匹配非字母数字</td></tr>
<tr><td>\s</td><td> 匹配任意空白字符，等价于 [\t\n\r\f].</td></tr>
<tr><td>\S</td><td>匹配任意非空字符</td></tr>
<tr><td>\d</td><td> 匹配任意数字，等价于 [0-9].</td></tr>
<tr><td>\D</td><td>匹配任意非数字</td></tr>
<tr><td>\A</td><td>匹配字符串开始</td></tr>
<tr><td>\Z</td><td>匹配字符串结束，如果是存在换行，只匹配到换行前的结束字符串。c</td></tr>
<tr><td>\z</td><td>匹配字符串结束</td></tr>
<tr><td>\G</td><td>匹配最后匹配完成的位置。</td></tr>
<tr><td>\b</td><td>匹配一个单词边界，也就是指单词和空格间的位置。例如， 'er\b' 可以匹配"never" 中的 'er'，但不能匹配 "verb" 中的 'er'。</td></tr>
<tr><td>\B</td><td>匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er'，但不能匹配 "never" 中的 'er'。</td></tr>
<tr><td>\n, \t, 等.</td><td>匹配一个换行符。匹配一个制表符。等</td></tr>
<tr><td>\1...\9</td><td>匹配第n个分组的子表达式。</td></tr>
<tr><td>\10</td><td>匹配第n个分组的子表达式，如果它经匹配。否则指的是八进制字符码的表达式。</td></tr>
</tbody></table>
<hr><h2>
正则表达式实例
</h2>
<h4>字符匹配</h4>
<table class="reference">
<tbody><tr><th style="width:25%">实例</th><th>描述</th></tr>
<tr><td>python</td><td>匹配 "python". </td></tr>
</tbody></table>
<h4>字符类</h4>
<table class="reference">
<tbody><tr><th style="width:25%">实例</th><th>描述</th></tr>
<tr><td>[Pp]ython </td><td>匹配 "Python" 或 "python"</td></tr>
<tr><td>rub[ye]</td><td>匹配 "ruby" 或 "rube"</td></tr>
<tr><td>[aeiou]</td><td>匹配中括号内的任意一个字母</td></tr>
<tr><td>[0-9]</td><td>匹配任何数字。类似于 [0123456789]</td></tr>
<tr><td>[a-z]</td><td>匹配任何小写字母</td></tr>
<tr><td>[A-Z]</td><td>匹配任何大写字母</td></tr>
<tr><td>[a-zA-Z0-9]</td><td>匹配任何字母及数字</td></tr>
<tr><td>[^aeiou]</td><td>除了aeiou字母以外的所有字符 
</td></tr>
<tr><td>[^0-9]</td><td>匹配除了数字外的字符 
</td></tr>
</tbody></table>

<h4>特殊字符类</h4>
<table class="reference">
<tbody><tr><th style="width:25%">实例</th><th>描述</th></tr>
<tr><td>.</td><td>匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符，请使用象 '[.\n]' 的模式。</td></tr>
<tr><td>\d</td><td>匹配一个数字字符。等价于 [0-9]。</td></tr>
<tr><td>\D </td><td>匹配一个非数字字符。等价于 [^0-9]。</td></tr>
<tr><td>\s</td><td>匹配任何空白字符，包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。</td></tr>
<tr><td>\S </td><td>匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。</td></tr>
<tr><td>\w</td><td>匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。</td></tr>
<tr><td>\W</td><td>匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。</td></tr>
</tbody></table>			
			
			</div></div><div data-role='page' id='cgi-programming.html'><div data-role='header'><h1>CGI编程</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('mysql.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 CGI编程</h1>
<hr>
<h2>什么是 CGI</h2>
<p>CGI 目前由NCSA维护，NCSA定义CGI如下：</p><p>
CGI(Common Gateway Interface),通用网关接口,它是一段程序,运行在服务器上如：HTTP服务器，提供同客户端HTML页面的接口。</p>

<hr><h2>网页浏览</h2>
<p>为了更好的了解CGI是如何工作的，我们可以从在网页上点击一个链接或URL的流程：</p>
<ul>
<li>
1、使用你的浏览器访问URL并连接到HTTP web 服务器。</li><li>
2、Web服务器接收到请求信息后会解析URL，并查找访问的文件在服务器上是否存在，如果存在返回文件的内容，否则返回错误信息。</li><li>
3、浏览器从服务器上接收信息，并显示接收的文件或者错误信息。</li></ul>

<p>CGI程序可以是Python脚本，PERL脚本，SHELL脚本，C或者C++程序等。</p>
<hr>
<h2>
CGI架构图
</h2>
<p><img src="cgiarch1.gif" alt="cgiarch" width="411" height="473" class="alignnone size-full wp-image-4561" /></p>
<hr>
<h2>Web服务器支持及配置</h2>
<p>在你进行CGI编程前，确保您的Web服务器支持CGI及已经配置了CGI的处理程序。</p>
<p>Apache 支持CGI 配置：</p>
<p>设置好CGI目录：</p>
<pre>
ScriptAlias /cgi-bin/ /var/www/cgi-bin/
</pre>

<p>
所有的HTTP服务器执行CGI程序都保存在一个预先配置的目录。这个目录被称为CGI目录，并按照惯例，它被命名为/var/www/cgi-bin目录。</p><p>
CGI文件的扩展名为.cgi，python也可以使用.py扩展名。</p><p>
默认情况下，Linux服务器配置运行的cgi-bin目录中为/var/www。</p><p>
如果你想指定其他运行CGI脚本的目录，可以修改httpd.conf配置文件，如下所示：</p>
<pre>
&lt;Directory "/var/www/cgi-bin"&gt;
   AllowOverride None
   Options +ExecCGI
   Order allow,deny
   Allow from all
&lt;/Directory&gt;
</pre>
<p>在 AddHandler 中添加 .py 后缀，这样我们就可以访问 .py 结尾的 python 脚本文件：</p>
<pre>
AddHandler cgi-script .cgi .pl .py</pre>
<hr><h2>第一个CGI程序</h2>
<p>我们使用Python创建第一个CGI程序，文件名为hello.py，文件位于/var/www/cgi-bin目录中，内容如下，修改文件的权限为755：</p>
<pre>
#!/usr/bin/python3

print ("Content-type:text/html\r\n\r\n")
print ('&lt;html&gt;')
print ('&lt;head&gt;')
print ('&lt;title&gt;Hello Word - First CGI Program&lt;/title&gt;')
print ('&lt;/head&gt;')
print ('&lt;body&gt;')
print ('&lt;h2&gt;Hello Word! This is my first CGI program&lt;/h2&gt;')
print ('&lt;/body&gt;')
print ('&lt;/html&gt;')
</pre>
<p>以上程序在浏览器访问显示结果如下：</p>
<pre>
Hello Word! This is my first CGI program
</pre>
<p>这个的hello.py脚本是一个简单的Python脚本，脚本第一行的输出内容"Content-type:text/html\r\n\r\n"发送到浏览器并告知浏览器显示的内容类型为"text/html"。</p>
<hr><h2>HTTP头部</h2>
<p>hello.py文件内容中的" Content-type:text/html\r\n\r\n"即为HTTP头部的一部分，它会发送给浏览器告诉浏览器文件的内容类型。</p>
<p>HTTP头部的格式如下：</p>
<pre>
HTTP 字段名: 字段内容

例如

Content-type: text/html\r\n\r\n
</pre>
<p>以下表格介绍了CGI程序中HTTP头部经常使用的信息：</p>
<table class="reference">
<tbody><tr>
<th style="width:30%">头</th><th>描述</th>
</tr>
<tr> <td>Content-type: </td><td>请求的与实体对应的MIME信息。例如: Content-type:text/html</td></tr>
<tr> <td>Expires: Date </td><td>响应过期的日期和时间</td> </tr>
<tr> <td>Location: URL </td><td>用来重定向接收方到非请求URL的位置来完成请求或标识新的资源</td> </tr>
<tr> <td>Last-modified: Date</td><td>请求资源的最后修改时间</td> </tr>
<tr> <td>Content-length: N</td><td>请求的内容长度</td> </tr>
<tr> <td>Set-Cookie: String </td><td>设置Http Cookie</td> </tr>
</tbody></table>
<hr>
<h2>CGI环境变量</h2>
<p>所有的CGI程序都接收以下的环境变量，这些变量在CGI程序中发挥了重要的作用：</p>
<table class="reference">
<tbody><tr><th style="width:30%;">变量名</th><th>描述</th></tr>
<tr> <td>CONTENT_TYPE</td><td>这个环境变量的值指示所传递来的信息的MIME类型。目前，环境变量CONTENT_TYPE一般都是：application/x-www-form-urlencoded,他表示数据来自于HTML表单。</td> </tr>
<tr> <td>CONTENT_LENGTH</td><td>如果服务器与CGI程序信息的传递方式是POST，这个环境变量即使从标准输入STDIN中可以读到的有效数据的字节数。这个环境变量在读取所输入的数据时必须使用。</td> </tr>
<tr> <td>HTTP_COOKIE</td><td>客户机内的 COOKIE 内容。</td> </tr>
<tr> <td>HTTP_USER_AGENT</td><td>提供包含了版本数或其他专有数据的客户浏览器信息。</td> </tr>
<tr> <td>PATH_INFO</td><td>这个环境变量的值表示紧接在CGI程序名之后的其他路径信息。它常常作为CGI程序的参数出现。</td> </tr>
<tr> <td>QUERY_STRING</td><td>如果服务器与CGI程序信息的传递方式是GET，这个环境变量的值即使所传递的信息。这个信息经跟在CGI程序名的后面，两者中间用一个问号'?'分隔。</td> </tr>
<tr> <td>REMOTE_ADDR</td><td>这个环境变量的值是发送请求的客户机的IP地址，例如上面的192.168.1.67。这个值总是存在的。而且它是Web客户机需要提供给Web服务器的唯一标识，可以在CGI程序中用它来区分不同的Web客户机。</td> </tr>
<tr> <td>REMOTE_HOST</td><td>这个环境变量的值包含发送CGI请求的客户机的主机名。如果不支持你想查询，则无需定义此环境变量。</td> </tr>
<tr> <td>REQUEST_METHOD</td><td>提供脚本被调用的方法。对于使用 HTTP/1.0 协议的脚本，仅 GET 和 POST 有意义。</td></tr>
<tr> <td>SCRIPT_FILENAME</td><td>CGI脚本的完整路径</td></tr>
<tr> <td>SCRIPT_NAME</td><td>CGI脚本的的名称</td></tr>
<tr> <td>SERVER_NAME</td><td>这是你的 WEB 服务器的主机名、别名或IP地址。</td></tr>
<tr> <td>SERVER_SOFTWARE</td><td>这个环境变量的值包含了调用CGI程序的HTTP服务器的名称和版本号。例如，上面的值为Apache/2.2.14(Unix)</td></tr>
</tbody></table>
<p>以下是一个简单的CGI脚本输出CGI的环境变量：</p>
<pre>
#!/usr/bin/python3

import os

print ("Content-type: text/html\r\n\r\n")
print ("&lt;font size=+1&gt;Environment&lt;/font&gt;&lt;\br&gt;")
for param in os.environ.keys():
  print ("&lt;b&gt;%20s&lt;/b&gt;: %s&lt;\br&gt;" % (param, os.environ[param]))
</pre>
<hr><h2>GET和POST方法</h2>
<p>浏览器客户端通过两种方法向服务器传递信息，这两种方法就是 GET 方法和 POST 方法。</p>

<h3>使用GET方法传输数据</h3>
<p>GET方法发送编码后的用户信息到服务端，数据信息包含在请求页面的URL上，以"?"号分割, 如下所示：</p>

<pre>
http://www.test.com/cgi-bin/hello.py?key1=value1&amp;key2=value2
</pre>
有关 GET 请求的其他一些注释：
<ul>
<li>GET 请求可被缓存</li>
<li>GET 请求保留在浏览器历史记录中</li>
<li>GET 请求可被收藏为书签</li>
<li>GET 请求不应在处理敏感数据时使用</li>
<li>GET 请求有长度限制</li>
<li>GET 请求只应当用于取回数据</li>
</ul>
<h3>简单的url实例：GET方法</h3>
<p>以下是一个简单的URL，使用GET方法向hello_get.py程序发送两个参数：</p>
<pre>
/cgi-bin/hello_get.py?first_name=ZARA&amp;last_name=ALI
</pre>
<p>以下为hello_get.py文件的代码：</p>
<pre>
#!/usr/bin/python3

# CGI处理模块
import cgi, cgitb 

# 创建 FieldStorage 的实例化
form = cgi.FieldStorage() 

# 获取数据
first_name = form.getvalue('first_name')
last_name  = form.getvalue('last_name')

print ("Content-type:text/html\r\n\r\n")
print ("&lt;html&gt;")
print ("&lt;head&gt;")
print ("&lt;title&gt;Hello - Second CGI Program&lt;/title&gt;")
print ("&lt;/head&gt;")
print ("&lt;body&gt;")
print ("&lt;h2&gt;Hello %s %s&lt;/h2&gt;" % (first_name, last_name))
print ("&lt;/body&gt;")
print ("&lt;/html&gt;")
</pre>
<p>浏览器请求输出结果：</p>
<pre>
Hello ZARA ALI
</pre>
<h3>简单的表单实例：GET方法</h3>
<p>以下是一个通过HTML的表单使用GET方法向服务器发送两个数据，提交的服务器脚本同样是hello_get.py文件，代码如下：</p>
<pre>
&lt;form action="/cgi-bin/hello_get.py" method="get"&gt;
First Name: &lt;input type="text" name="first_name"&gt;  &lt;br /&gt;

Last Name: &lt;input type="text" name="last_name" /&gt;
&lt;input type="submit" value="Submit" /&gt;
&lt;/form&gt;
</pre>
<h3>使用POST方法传递数据</h3>
<p>使用POST方法向服务器传递数据是更安全可靠的，像一些敏感信息如用户密码等需要使用POST传输数据。</p>
<p>以下同样是hello_get.py ，它也可以处理浏览器提交的POST表单数据:</p>
<pre>
#!/usr/bin/python3

# 引入 CGI 模块 
import cgi, cgitb 

# 创建 FieldStorage 实例
form = cgi.FieldStorage() 

# 获取表单数据
first_name = form.getvalue('first_name')
last_name  = form.getvalue('last_name')

print ("Content-type:text/html\r\n\r\n")
print ("&lt;html&gt;")
print ("&lt;head&gt;")
print ("&lt;title&gt;Hello - Second CGI Program&lt;/title&gt;")
print ("&lt;/head&gt;")
print ("&lt;body&gt;")
print ("&lt;h2&gt;Hello %s %s&lt;/h2&gt;" % (first_name, last_name))
print ("&lt;/body&gt;")
print ("&lt;/html&gt;")
</pre>
<p>以下为表单通过POST方法向服务器脚本hello_get.py提交数据:</p>

<pre>
&lt;form action="/cgi-bin/hello_get.py" method="post"&gt;
First Name: &lt;input type="text" name="first_name"&gt;&lt;br /&gt;
Last Name: &lt;input type="text" name="last_name" /&gt;

&lt;input type="submit" value="Submit" /&gt;
&lt;/form&gt;
</pre>
<h3>通过CGI程序传递checkbox数据</h3>
<p>checkbox用于提交一个或者多个选项数据，HTML代码如下：</p>
<pre>
&lt;form action="/cgi-bin/checkbox.cgi" method="POST" target="_blank"&gt;
&lt;input type="checkbox" name="maths" value="on" /&gt; Maths
&lt;input type="checkbox" name="physics" value="on" /&gt; Physics
&lt;input type="submit" value="Select Subject" /&gt;
&lt;/form&gt;
</pre>
<p>以下为 checkbox.cgi 文件的代码：</p>
<pre>
#!/usr/bin/python3

# 引入 CGI 处理模块 
import cgi, cgitb 

# 创建 FieldStorage的实例 
form = cgi.FieldStorage() 

# 接收字段数据
if form.getvalue('maths'):
   math_flag = "ON"
else:
   math_flag = "OFF"

if form.getvalue('physics'):
   physics_flag = "ON"
else:
   physics_flag = "OFF"

print ("Content-type:text/html\r\n\r\n")
print ("&lt;html&gt;")
print ("&lt;head&gt;")
print ("&lt;title&gt;Checkbox - Third CGI Program&lt;/title&gt;")
print ("&lt;/head&gt;")
print ("&lt;body&gt;")
print ("&lt;h2&gt; CheckBox Maths is : %s&lt;/h2&gt;" % math_flag)
print ("&lt;h2&gt; CheckBox Physics is : %s&lt;/h2&gt;" % physics_flag)
print ("&lt;/body&gt;")
print ("&lt;/html&gt;")
</pre>
<h3>通过CGI程序传递Radio数据</h3>
<p>Radio只向服务器传递一个数据，HTML代码如下：</p>
<pre>
&lt;form action="/cgi-bin/radiobutton.py" method="post" target="_blank"&gt;
&lt;input type="radio" name="subject" value="maths" /&gt; Maths
&lt;input type="radio" name="subject" value="physics" /&gt; Physics
&lt;input type="submit" value="Select Subject" /&gt;
&lt;/form&gt;
</pre>
<p>radiobutton.py 脚本代码如下：</p>
<pre>
#!/usr/bin/python3

# 导入cgi 处理模块
import cgi, cgitb 

# 创建 of FieldStorage 实例
form = cgi.FieldStorage() 

# 从表单中获取数据
if form.getvalue('subject'):
   subject = form.getvalue('subject')
else:
   subject = "Not set"

print ("Content-type:text/html\r\n\r\n")
print ("&lt;html&gt;")
print ("&lt;head&gt;")
print ("&lt;title&gt;Radio - Fourth CGI Program&lt;/title&gt;")
print ("&lt;/head&gt;")
print ("&lt;body&gt;")
print ("&lt;h2&gt; Selected Subject is %s&lt;/h2&gt;" % subject)
print ("&lt;/body&gt;")
print ("&lt;/html&gt;")
</pre>
<h3>通过CGI程序传递 Textarea 数据</h3>
<p>Textarea向服务器传递多行数据，HTML代码如下：</p>
<pre>
&lt;form action="/cgi-bin/textarea.py" method="post" target="_blank"&gt;
&lt;textarea name="textcontent" cols="40" rows="4"&gt;
Type your text here...
&lt;/textarea&gt;
&lt;input type="submit" value="Submit" /&gt;
&lt;/form&gt;
</pre>
<p>textarea.cgi脚本代码如下：</p>
<pre>
#!/usr/bin/python3

# 导入cgi 处理模块
import cgi, cgitb 

# 创建 FieldStorage 实例
form = cgi.FieldStorage() 

# 从表单中获取数据
if form.getvalue('textcontent'):
   text_content = form.getvalue('textcontent')
else:
   text_content = "Not entered"

print ("Content-type:text/html\r\n\r\n")
print ("&lt;html&gt;")
print ("&lt;head&gt;")
print ("&lt;title&gt;Text Area - Fifth CGI Program&lt;/title&gt;")
print ("&lt;/head&gt;")
print ("&lt;body&gt;")
print ("&lt;h2&gt; Entered Text Content is %s&lt;/h2&gt;" % text_content)
print ("&lt;/body&gt;")
</pre>
<h3>通过CGI程序传递下拉数据</h3>
<p>HTML下拉框代码如下：</p>
<pre>
&lt;form action="/cgi-bin/dropdown.py" method="post" target="_blank"&gt;
&lt;select name="dropdown"&gt;
&lt;option value="Maths" selected&gt;Maths&lt;/option&gt;
&lt;option value="Physics"&gt;Physics&lt;/option&gt;
&lt;/select&gt;
&lt;input type="submit" value="Submit"/&gt;
&lt;/form&gt;
</pre>
<p>dropdown.py 脚本代码如下所示：</p>
<pre>
#!/usr/bin/python3

# 导入cgi 处理模块
import cgi, cgitb 

# 创建 FieldStorage 实例
form = cgi.FieldStorage() 

# 从表单中获取数据
if form.getvalue('dropdown'):
   subject = form.getvalue('dropdown')
else:
   subject = "Not entered"

print ("Content-type:text/html\r\n\r\n")
print ("&lt;html&gt;")
print ("&lt;head&gt;")
print ("&lt;title&gt;Dropdown Box - Sixth CGI Program&lt;/title&gt;")
print ("&lt;/head&gt;")
print ("&lt;body&gt;")
print ("&lt;h2&gt; Selected Subject is %s&lt;/h2&gt;" % subject)
print ("&lt;/body&gt;")
print ("&lt;/html&gt;")
</pre>
<hr>
<h2>CGI中使用Cookie</h2>
<p>在http协议一个很大的缺点就是不作用户身份的判断，这样给编程人员带来很大的不便， </p>
而cookie功能的出现弥补了这个缺憾。</p><p> 
所有cookie就是在客户访问脚本的同时，通过客户的浏览器，在客户硬盘上写入纪录数据 
，当下次客户访问脚本时取回数据信息，从而达到身份判别的功能，cookie常用在密码判断中 。</p>
　 
<h3>cookie的语法</h3> 
<p>http cookie的发送是通过http头部来实现的，他早于文件的传递，头部set-cookie的语法如下：</p>
<pre>
Set-cookie:name=name;expires=date;path=path;domain=domain;secure 
</pre>
<ul>
<li> 

name=name: 需要设置cookie的值(name不能使用"；"和"，"号),有多个name值时用"；"分隔例如：name1=name1;name2=name2;name3=name3。 </li> <li>
expires=date: cookie的有效期限,格式： expires="Wdy,DD-Mon-YYYY HH:MM:SS"</li> <li>
</li> <li>path=path: 设置cookie支持的路径,如果path是一个路径，则cookie对这个目录下的所有文件及子目录生效，例如： path="/cgi-bin/"，如果path是一个文件，则cookie指对这个文件生效，例如：path="/cgi-bin/cookie.cgi"。
</li> <li>domain=domain: 对cookie生效的域名，例如：domain="www.chinalb.com"
</li> <li>secure: 如果给出此标志，表示cookie只能通过SSL协议的https服务器来传递。 
</li> <li>cookie的接收是通过设置环境变量HTTP_COOKIE来实现的，CGI程序可以通过检索该变量获取cookie信息。</li></ul>
<hr><h2>Cookie设置 </h2>
<p>Cookie的设置非常简单，cookie会在http头部单独发送。以下实例在cookie中设置了UserID 和 Password：</p>
<pre>
&lt;pre&gt;
#!/usr/bin/python3

print ("Set-Cookie:UserID=XYZ;\r\n")
print ("Set-Cookie:Password=XYZ123;\r\n")
print ("Set-Cookie:Expires=Tuesday, 31-Dec-2007 23:12:40 GMT";\r\n")
print ("Set-Cookie:Domain=www.w3cschool.cc;\r\n")
print ("Set-Cookie:Path=/perl;\n")
print ("Content-type:text/html\r\n\r\n")
...........HTML 其他部分内容....
</pre>
<p>以上实例使用了 Set-Cookie 头信息来设置Cookie信息，可选项中设置了Cookie的其他属性，如过期时间Expires，域名Domain，路径Path。这些信息设置在 "Content-type:text/html\r\n\r\n"之前。
</p>
<hr>
<h2>
检索Cookie信息</h2><p>
Cookie信息检索页非常简单，Cookie信息存储在CGI的环境变量HTTP_COOKIE中，存储格式如下：</p>

<pre>
key1=value1;key2=value2;key3=value3....
</pre>
<p>以下是一个简单的CGI检索cookie信息的程序：</p>
<pre>
#!/usr/bin/python3

# 导入cgi 处理模块
from os import environ
import cgi, cgitb

if environ.has_key('HTTP_COOKIE'):
   for cookie in map(strip, split(environ['HTTP_COOKIE'], ';')):
      (key, value ) = split(cookie, '=');
      if key == "UserID":
         user_id = value

      if key == "Password":
         password = value

print ("User ID  = %s" % user_id)
print ("Password = %s" % password)
</pre>
<p>以上脚本输出结果如下：</p>
<pre>
User ID = XYZ
Password = XYZ123
</pre>
<p>文件上传实例：</p>
<p>HTML设置上传文件的表单需要设置enctype 属性为multipart/form-data，代码如下所示：</p>
<pre>
&lt;html&gt;
&lt;body&gt;
   &lt;form enctype="multipart/form-data" 
                     action="save_file.py" method="post"&gt;
   &lt;p&gt;File: &lt;input type="file" name="filename" /&gt;&lt;/p&gt;
   &lt;p&gt;&lt;input type="submit" value="Upload" /&gt;&lt;/p&gt;
   &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;
</pre>
<p>save_file.py脚本文件代码如下：</p>
<pre>
#!/usr/bin/python3

import cgi, os
import cgitb; cgitb.enable()

form = cgi.FieldStorage()

# 获取文件名
fileitem = form['filename']

# 检测文件是否上传
if fileitem.filename:
   # 设置文件路径 
   fn = os.path.basename(fileitem.filename)
   open('/tmp/' + fn, 'wb').write(fileitem.file.read())

   message = 'The file "' + fn + '" was uploaded successfully'
   
else:
   message = 'No file was uploaded'
   
print ("""\
Content-Type: text/html\n
&lt;html&gt;
&lt;body&gt;
   &lt;p&gt;%s&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
""" % (message,))
</pre>
<p>如果你使用的系统是Unix/Linux，你必须替换文件分隔符，在window下只需要使用open()语句即可：</p>
<pre>
fn = os.path.basename(fileitem.filename.replace("\\", "/" ))
</pre>
<hr><h2>文件下载对话框</h2>
<p>我们先在当前目录下创建 foo.txt 文件，用于程序的下载。</p>
<p>文件下载通过设置HTTP头信息来实现，功能代码如下：</p>
<pre>
#!/usr/bin/python3

# HTTP 头部
print ("Content-Disposition: attachment; filename=\"foo.txt\"\r\n\n")

# 打开文件
fo = open("foo.txt", "rb")

str = fo.read()
print (str)

# 关闭文件
fo.close()
</pre>			
			
			</div></div><div data-role='page' id='mysql.html'><div data-role='header'><h1>MySQL 数据库连接</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('socket.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
<h1>Python3 MySQL 数据库连接</h1>
<p>本文我们为大家介绍 Python3 使用 <a href="#" target="_blank">PyMySQL</a> 连接数据库，并实现简单的增删改查。</p>
<h3>什么是 PyMySQL？</h3>
<p>PyMySQL 是在 Python3.x 版本中用于连接 MySQL 服务器的一个库，Python2中则使用mysqldb。</p>
<p>PyMySQL 遵循 Python 数据库 API v2.0 规范，并包含了 pure-Python MySQL 客户端库。</p>
<hr>
<h2>PyMySQL 安装</h2>
<p>在使用 PyMySQL 之前，我们需要确保 PyMySQL 已安装。</p>
<p>PyMySQL 下载地址：https://github.com/PyMySQL/PyMySQL。</p>
<p>如果还未安装，我们可以使用以下命令安装最新版的 PyMySQL：</p>
<pre>
$ pip install PyMySQL
</pre>
<p>如果你的系统不支持 pip 命令，可以使用以下方式安装：</p>
<p>1、使用 git 命令下载安装包安装(你也可以手动下载)：</p>
<pre>
$ git clone https://github.com/PyMySQL/PyMySQL
$ cd PyMySQL/
$ python3 setup.py install
</pre>
<p>2、如果需要制定版本号，可以使用 curl 命令来安装：</p>
<pre>
$ # X.X 为 PyMySQL 的版本号
$ curl -L https://github.com/PyMySQL/PyMySQL/tarball/pymysql-X.X | tar xz
$ cd PyMySQL*
$ python3 setup.py install
$ # 现在你可以删除 PyMySQL* 目录
</pre>
<p><strong>注意：</strong>请确保您有root权限来安装上述模块。</p>
<blockquote><p>安装的过程中可能会出现"ImportError: No module named setuptools"的错误提示，意思是你没有安装setuptools，你可以访问<a href="#" target="_blank">https://pypi.python.org/pypi/setuptools</a> 找到各个系统的安装方法。
</p>
<p>Linux 系统安装实例：</p>
<pre>
$ wget https://bootstrap.pypa.io/ez_setup.py
$ python3 ez_setup.py
</pre>
</blockquote>
<hr>
<h2>数据库连接</h2>
<p>连接数据库前，请先确认以下事项：</p>
<ul>
<li>您已经创建了数据库 TESTDB.</li>
<li>在TESTDB数据库中您已经创建了表 EMPLOYEE</li>
<li>EMPLOYEE表字段为 FIRST_NAME, LAST_NAME, AGE, SEX 和 INCOME。</li>
<li>连接数据库TESTDB使用的用户名为 "testuser" ，密码为 "test123",你可以可以自己设定或者直接使用root用户名及其密码，Mysql数据库用户授权请使用Grant命令。</li>
<li>在你的机子上已经安装了 Python MySQLdb 模块。</li>
<li>如果您对sql语句不熟悉，可以访问我们的 <a href="/sql/sql-tutorial.html">SQL基础教程</a>
</li>
</ul>
<h3>实例：</h3>
<p>以下实例链接Mysql的TESTDB数据库：</p>
<pre>
#!/usr/bin/python3

import PyMySQL

# 打开数据库连接
db = PyMySQL.connect("localhost","testuser","test123","TESTDB" )

# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()

# 使用 execute()  方法执行 SQL 查询 
cursor.execute("SELECT VERSION()")

# 使用 fetchone() 方法获取单条数据.
data = cursor.fetchone()

print ("Database version : %s " % data)

# 关闭数据库连接
db.close()
</pre>
<p>执行以上脚本输出结果如下：</p>
<pre>
Database version : 5.5.20-log
</pre>
<hr>
<h2>
创建数据库表</h2><p>
如果数据库连接存在我们可以使用execute()方法来为数据库创建表，如下所示创建表EMPLOYEE：</p>
<pre>
#!/usr/bin/python3

import PyMySQL

# 打开数据库连接
db = PyMySQL.connect("localhost","testuser","test123","TESTDB" )

# 使用 cursor() 方法创建一个游标对象 cursor
cursor = db.cursor()

# 使用 execute() 方法执行 SQL，如果表存在则删除
cursor.execute("DROP TABLE IF EXISTS EMPLOYEE")

# 使用预处理语句创建表
sql = """CREATE TABLE EMPLOYEE (
         FIRST_NAME  CHAR(20) NOT NULL,
         LAST_NAME  CHAR(20),
         AGE INT,  
         SEX CHAR(1),
         INCOME FLOAT )"""

cursor.execute(sql)

# 关闭数据库连接
db.close()
</pre>
<hr>
<h2>数据库插入操作</h2><p>
以下实例使用执行 SQL INSERT 语句向表 EMPLOYEE 插入记录：</p>
<pre>
#!/usr/bin/python3

import PyMySQL

# 打开数据库连接
db = PyMySQL.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 插入语句
sql = """INSERT INTO EMPLOYEE(FIRST_NAME,
         LAST_NAME, AGE, SEX, INCOME)
         VALUES ('Mac', 'Mohan', 20, 'M', 2000)"""
try:
   # 执行sql语句
   cursor.execute(sql)
   # 提交到数据库执行
   db.commit()
except:
   # 如果发生错误则回滚
   db.rollback()

# 关闭数据库连接
db.close()
</pre>
<p>以上例子也可以写成如下形式：</p>
<pre>
#!/usr/bin/python3

import PyMySQL

# 打开数据库连接
db = PyMySQL.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 插入语句
sql = "INSERT INTO EMPLOYEE(FIRST_NAME, \
       LAST_NAME, AGE, SEX, INCOME) \
       VALUES ('%s', '%s', '%d', '%c', '%d' )" % \
       ('Mac', 'Mohan', 20, 'M', 2000)
try:
   # 执行sql语句
   cursor.execute(sql)
   # 执行sql语句
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

# 关闭数据库连接
db.close()
</pre>
<p>以下代码使用变量向SQL语句中传递参数:</p>
<pre>
..................................
user_id = "test123"
password = "password"

con.execute('insert into Login values("%s", "%s")' % \
             (user_id, password))
..................................
</pre>
<hr>
<h2>数据库查询操作</h2>
<p>Python查询Mysql使用 fetchone() 方法获取单条数据, 使用fetchall() 方法获取多条数据。</p>
<ul> <li><b>fetchone():</b> 该方法获取下一个查询结果集。结果集是一个对象</li> <li><b>fetchall(): </b>接收全部的返回结果行.</li> <li><b>rowcount:</b> 这是一个只读属性，并返回执行execute()方法后影响的行数。</li> </ul>
<h3>实例：</h3>
<p>查询EMPLOYEE表中salary（工资）字段大于1000的所有数据：</p>
<pre>
#!/usr/bin/python3

import PyMySQL

# 打开数据库连接
db = PyMySQL.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 查询语句
sql = "SELECT * FROM EMPLOYEE \
       WHERE INCOME &gt; '%d'" % (1000)
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 获取所有记录列表
   results = cursor.fetchall()
   for row in results:
      fname = row[0]
      lname = row[1]
      age = row[2]
      sex = row[3]
      income = row[4]
       # 打印结果
      print ("fname=%s,lname=%s,age=%d,sex=%s,income=%d" % \
             (fname, lname, age, sex, income ))
except:
   print ("Error: unable to fecth data")

# 关闭数据库连接
db.close()
</pre>
<p>以上脚本执行结果如下：</p>
<pre>
fname=Mac, lname=Mohan, age=20, sex=M, income=2000
</pre><hr>
<h2>数据库更新操作</h2>
<p>更新操作用于更新数据表的的数据，以下实例将 TESTDB表中的 SEX 字段全部修改为 'M'，AGE 字段递增1：</p>
<pre>
#!/usr/bin/python3

import PyMySQL

# 打开数据库连接
db = PyMySQL.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 更新语句
sql = "UPDATE EMPLOYEE SET AGE = AGE + 1
                          WHERE SEX = '%c'" % ('M')
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 提交到数据库执行
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

# 关闭数据库连接
db.close()
</pre>
<hr>
<h2>删除操作</h2>
<p>删除操作用于删除数据表中的数据，以下实例演示了删除数据表 EMPLOYEE 中 AGE 大于 20 的所有数据：</p>
<pre>
#!/usr/bin/python3

import PyMySQL

# 打开数据库连接
db = PyMySQL.connect("localhost","testuser","test123","TESTDB" )

# 使用cursor()方法获取操作游标 
cursor = db.cursor()

# SQL 删除语句
sql = "DELETE FROM EMPLOYEE WHERE AGE &gt; '%d'" % (20)
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 提交修改
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()

# 关闭连接
db.close()
</pre>
<hr>
<h2>执行事务</h2>
<p>事务机制可以确保数据一致性。</p>
<p>事务应该具有4个属性：原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。</p>
<ul> <li>原子性（atomicity）。一个事务是一个不可分割的工作单位，事务中包括的诸操作要么都做，要么都不做。</li><li> 一致性（consistency）。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。</li><li> 隔离性（isolation）。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的，并发执行的各个事务之间不能互相干扰。</li><li> 持久性（durability）。持续性也称永久性（permanence），指一个事务一旦提交，它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。 </li></ul>
<p>Python DB API 2.0 的事务提供了两个方法 commit 或 rollback。</p>
<h3>实例</h3>
<pre>
# SQL删除记录语句
sql = "DELETE FROM EMPLOYEE WHERE AGE &gt; '%d'" % (20)
try:
   # 执行SQL语句
   cursor.execute(sql)
   # 向数据库提交
   db.commit()
except:
   # 发生错误时回滚
   db.rollback()
</pre>
<p>对于支持事务的数据库， 在Python数据库编程中，当游标建立之时，就自动开始了一个隐形的数据库事务。 </p>
<p>commit()方法游标的所有更新操作，rollback（）方法回滚当前游标的所有操作。每一个方法都开始了一个新的事务。</p>
<hr>
<h2>错误处理</h2>
<p>DB API中定义了一些数据库操作的错误及异常，下表列出了这些错误和异常:</p>
<table class="reference"> <tbody><tr> <th style="width:15%">异常</th><th>描述</th> </tr> <tr><td>Warning</td><td>当有严重警告时触发，例如插入数据是被截断等等。必须是 StandardError 的子类。</td></tr> <tr><td>Error</td><td>警告以外所有其他错误类。必须是 StandardError 的子类。</td></tr> <tr><td>InterfaceError</td><td>当有数据库接口模块本身的错误（而不是数据库的错误）发生时触发。 必须是Error的子类。</td></tr> <tr><td>DatabaseError</td><td>和数据库有关的错误发生时触发。 必须是Error的子类。</td></tr> <tr><td>DataError</td><td>当有数据处理时的错误发生时触发，例如：除零错误，数据超范围等等。 必须是DatabaseError的子类。</td></tr> <tr><td>OperationalError</td><td>指非用户控制的，而是操作数据库时发生的错误。例如：连接意外断开、 数据库名未找到、事务处理失败、内存分配错误等等操作数据库是发生的错误。 必须是DatabaseError的子类。</td></tr> <tr><td>IntegrityError</td><td>完整性相关的错误，例如外键检查失败等。必须是DatabaseError子类。</td></tr> <tr><td>InternalError</td><td> 数据库的内部错误，例如游标（cursor）失效了、事务同步失败等等。 必须是DatabaseError子类。</td></tr> <tr><td>ProgrammingError</td><td>程序错误，例如数据表（table）没找到或已存在、SQL语句语法错误、 参数数量错误等等。必须是DatabaseError的子类。</td></tr> <tr><td>NotSupportedError</td><td>不支持错误，指使用了数据库不支持的函数或API等。例如在连接对象上 使用.rollback()函数，然而数据库并不支持事务或者事务已关闭。 必须是DatabaseError的子类。</td></tr> </tbody></table>
</div></div><div data-role='page' id='socket.html'><div data-role='header'><h1>网络编程</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('smtp.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 网络编程</h1>
<p>Python 提供了两个级别访问的网络服务。：</p>
<ul>
<li>低级别的网络服务支持基本的 Socket，它提供了标准的 BSD Sockets API，可以访问底层操作系统Socket接口的全部方法。</li>
<li>高级别的网络服务模块 SocketServer， 它提供了服务器中心类，可以简化网络服务器的开发。</li>
</ul>
<hr>
<h2>什么是 Socket?</h2>
<p>Socket又称"套接字"，应用程序通常通过"套接字"向网络发出请求或者应答网络请求，使主机间或者一台计算机上的进程间可以通讯。</p>

<hr><h2>socket()函数</h2>
<p>Python 中，我们用 socket（）函数来创建套接字，语法格式如下：</p>
<pre>
socket.socket([family[, type[, proto]]])
</pre>
<h3>参数</h3>
<ul>
<li>family: 套接字家族可以使AF_UNIX或者AF_INET</li>
<li>type: 套接字类型可以根据是面向连接的还是非连接分为<code>SOCK_STREAM</code>或<code>SOCK_DGRAM</code></li>
<li>protocol: 一般不填默认为0.</li>
</ul>
<h3>Socket 对象(内建)方法</h3>
<table class="reference"><thead>
<tr>
<th>函数</th>
<th>描述</th>
</tr>
</thead><tbody>
<tr>
<td colspan="2">服务器端套接字</td>

</tr>
<tr>
<td>s.bind()</td>
<td>绑定地址（host,port）到套接字， 在AF_INET下,以元组（host,port）的形式表示地址。</td>
</tr>
<tr>
<td>s.listen()</td>
<td>开始TCP监听。backlog指定在拒绝连接之前，操作系统可以挂起的最大连接数量。该值至少为1，大部分应用程序设为5就可以了。</td>
</tr>
<tr>
<td>s.accept()</td>
<td>被动接受TCP客户端连接,(阻塞式)等待连接的到来</td>
</tr>
<tr>
<td colspan="2">客户端套接字</td>

</tr>
<tr>
<td>s.connect()</td>
<td>主动初始化TCP服务器连接，。一般address的格式为元组（hostname,port），如果连接出错，返回socket.error错误。</td>
</tr>
<tr>
<td>s.connect_ex()</td>
<td>connect()函数的扩展版本,出错时返回出错码,而不是抛出异常</td>
</tr>
<tr>
<td colspan="2">公共用途的套接字函数</td>

</tr>
<tr>
<td>s.recv()</td>
<td>接收TCP数据，数据以字符串形式返回，bufsize指定要接收的最大数据量。flag提供有关消息的其他信息，通常可以忽略。</td>
</tr>
<tr>
<td>s.send()</td>
<td>发送TCP数据，将string中的数据发送到连接的套接字。返回值是要发送的字节数量，该数量可能小于string的字节大小。</td>
</tr>
<tr>
<td>s.sendall()</td>
<td>完整发送TCP数据，完整发送TCP数据。将string中的数据发送到连接的套接字，但在返回之前会尝试发送所有数据。成功返回None，失败则抛出异常。</td>
</tr>
<tr>
<td>s.recvform()</td>
<td>接收UDP数据，与recv()类似，但返回值是（data,address）。其中data是包含接收数据的字符串，address是发送数据的套接字地址。</td>
</tr>
<tr>
<td>s.sendto()</td>
<td>发送UDP数据，将数据发送到套接字，address是形式为（ipaddr，port）的元组，指定远程地址。返回值是发送的字节数。</td>
</tr>
<tr>
<td>s.close()</td>
<td>关闭套接字</td>
</tr>
<tr>
<td>s.getpeername()</td>
<td>返回连接套接字的远程地址。返回值通常是元组（ipaddr,port）。</td>
</tr>
<tr>
<td>s.getsockname()</td>
<td>返回套接字自己的地址。通常是一个元组(ipaddr,port)</td>
</tr>
<tr>
<td>s.setsockopt(level,optname,value)</td>
<td>设置给定套接字选项的值。</td>
</tr>
<tr>
<td>s.getsockopt(level,optname[.buflen])</td>
<td>返回套接字选项的值。</td>
</tr>
<tr>
<td>s.settimeout(timeout)</td>
<td>设置套接字操作的超时期，timeout是一个浮点数，单位是秒。值为None表示没有超时期。一般，超时期应该在刚创建套接字时设置，因为它们可能用于连接的操作（如connect()）</td>
</tr>
<tr>
<td>s.gettimeout()</td>
<td>返回当前超时期的值，单位是秒，如果没有设置超时期，则返回None。</td>
</tr>
<tr>
<td>s.fileno()</td>
<td>返回套接字的文件描述符。</td>
</tr>
<tr>
<td>s.setblocking(flag)</td>
<td>如果flag为0，则将套接字设为非阻塞模式，否则将套接字设为阻塞模式（默认值）。非阻塞模式下，如果调用recv()没有发现任何数据，或send()调用无法立即发送数据，那么将引起socket.error异常。</td>
</tr>
<tr>
<td>s.makefile()</td>
<td>创建一个与该套接字相关连的文件</td>
</tr>
</tbody></table>



<hr>
<h2>简单实例</h2>
<h3>服务端</h3>
<p>我们使用 socket 模块的 <b>socket</b> 函数来创建一个 socket 对象。socket 对象可以通过调用其他函数来设置一个 socket 服务。</p>
<p>现在我们可以通过调用 <b>bind(hostname, port)</b> 函数来指定服务的 <i>port(端口)</i>。</p>
<p>接着，我们调用 socket 对象的 <i>accept</i> 方法。该方法等待客户端的连接，并返回 <i>connection</i> 对象，表示已连接到客户端。</p>
<p>完整代码如下：</p>
<pre>
#!/usr/bin/python3
# 文件名：server.py

# 导入 socket 模块
import socket

# 创建 socket 对象
serversocket = socket.socket(
            socket.AF_INET, socket.SOCK_STREAM) 

# 获取本地主机名
host = socket.gethostname()

port = 9999

# 绑定端口
serversocket.bind((host, port))

# 设置最大连接数，超过后排队
serversocket.listen(5)

while True:
    # 建立客户端连接
    clientsocket,addr = serversocket.accept()      

    print("连接地址: %s" % str(addr))
    
    msg='欢迎访问菜鸟教程！'+ "\r\n"
    clientsocket.send(msg.encode('utf-8'))
    clientsocket.close()
</pre>
<h3>客户端</h3>
<p>接下来我们写一个简单的客户端实例连接到以上创建的服务。端口号为 12345。</p>
<p><b>socket.connect(hosname, port )</b> 方法打开一个 TCP 连接到主机为 <i>hostname</i> 端口为 <i>port</i> 的服务商。连接后我们就可以从服务端后期数据，记住，操作完成后需要关闭连接。</p>
<p>完整代码如下：</p>
<pre>
#!/usr/bin/python3
# 文件名：client.py

# 导入 socket 模块
import socket

# 创建 socket 对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 

# 获取本地主机名
host = socket.gethostname() 

# 设置端口好
port = 9999

# 连接服务，指定主机和端口
s.connect((host, port))

# 接收小于 1024 字节的数据
msg = s.recv(1024)

s.close()

print (msg.decode('utf-8'))
</pre>
<p>现在我们打开连个终端，第一个终端执行 server.py 文件：</p>
<pre>$ python3 server.py</pre>
<p>第二个终端执行 client.py 文件：</p>
<pre>
$ python3 client.py 
欢迎访问菜鸟教程！

</pre>
<p>这是我们再打开第一个终端，就会看到有以下信息输出：</p>
<pre>
连接地址： ('192.168.0.118', 33397)
</pre>
<hr>
<h2>Python Internet 模块</h2>
<p>以下列出了 Python 网络编程的一些重要模块：</p>
<table class="reference">
<tbody><tr>
<th style="width:10%">协议</th><th style="width:30%">功能用处</th><th style="width:15%">端口号</th><th>Python 模块</th>
</tr>
<tr><td>HTTP</td><td>网页访问</td><td>80</td><td>httplib, urllib, xmlrpclib</td></tr>
<tr><td>NNTP</td><td>阅读和张贴新闻文章，俗称为"帖子"</td><td>119</td><td>nntplib</td></tr>
<tr><td>FTP</td><td>文件传输</td><td>20</td><td>ftplib, urllib</td></tr>
<tr><td>SMTP</td><td>发送邮件</td><td>25</td><td>smtplib</td></tr>
<tr><td>POP3</td><td>接收邮件</td><td>110</td><td>poplib</td></tr>
<tr><td>IMAP4</td><td>获取邮件</td><td>143</td><td>imaplib</td></tr>
<tr><td>Telnet</td><td>命令行</td><td>23</td><td>telnetlib</td></tr>
<tr><td>Gopher</td><td>信息查找</td><td>70</td><td>gopherlib, urllib</td></tr>
</tbody></table>

<p>更多内容可以参阅官网的 <a href="#" title="Python Socket 库" target="_blank">Python Socket Library and Modules</a>。</p>			
			
			</div></div><div data-role='page' id='smtp.html'><div data-role='header'><h1>SMTP发送邮件</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('multithreading.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 SMTP发送邮件</h1>

<p>SMTP（Simple Mail Transfer Protocol）即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则，由它来控制信件的中转方式。</p>
<p>python的smtplib提供了一种很方便的途径发送电子邮件。它对smtp协议进行了简单的封装。</p>
<p>Python创建 SMTP 对象语法如下：</p>
<pre>
import smtplib

smtpObj = smtplib.SMTP( [host [, port [, local_hostname]]] )
</pre>
<p>参数说明：</p>
<ul>
<li>
host:  SMTP 服务器主机。 你可以指定主机的ip地址或者域名如:w3cschool.cc，这个是可选参数。
</li><li>
port: 如果你提供了 host 参数, 你需要指定 SMTP 服务使用的端口号，一般情况下SMTP端口号为25。 
</li><li>
local_hostname: 如果SMTP在你的本机上，你只需要指定服务器地址为 localhost 即可。
</li></ul>
<p>Python SMTP对象使用sendmail方法发送邮件，语法如下：</p>
<pre>
SMTP.sendmail(from_addr, to_addrs, msg[, mail_options, rcpt_options]
</pre>
<p>参数说明：</p>
<ul>
<li>
from_addr:  邮件发送者地址。
</li><li>
to_addrs: 字符串列表，邮件发送地址。
</li><li>
msg: 发送消息
</li></ul>
<p>这里要注意一下第三个参数，msg是字符串，表示邮件。我们知道邮件一般由标题，发信人，收件人，邮件内容，附件等构成，发送邮件的时候，要注意msg的格式。这个格式就是smtp协议中定义的格式。</p>
<h3>实例</h3>
<p>以下是一个使用Python发送邮件简单的实例：</p>
<pre>
#!/usr/bin/python3

import smtplib
from email.mime.text import MIMEText
from email.header import Header

sender = 'from@runoob.com'
receivers = ['429240967@qq.com']  # 接收邮件，可设置为你的QQ邮箱或者其他邮箱

# 三个参数：第一个为文本内容，第二个 plain 设置文本格式，第三个 utf-8 设置编码
message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8')
message['From'] = Header("菜鸟教程", 'utf-8')
message['To'] =  Header("测试", 'utf-8')

subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')


try:
    smtpObj = smtplib.SMTP('localhost')
    smtpObj.sendmail(sender, receivers, message.as_string())
    print ("邮件发送成功")
except smtplib.SMTPException:
    print ("Error: 无法发送邮件")
</pre>

<p>我们使用三个引号来设置邮件信息，标准邮件需要三个头部信息： <b>From</b>, <b>To</b>, 和 <b>Subject</b> ，每个信息直接使用空行分割。</p>
<p>我们通过实例化 smtplib 模块的 SMTP 对象 <i>smtpObj</i> 来连接到 SMTP 访问，并使用 <i>sendmail</i> 方法来发送信息。</p>
<p>执行以上程序，如果你本机安装sendmail，就会输出：</p>
<pre>
$ python3 test.py 
邮件发送成功
</pre>
<p>查看我们的收件箱(一般在垃圾箱)，就可以查看到邮件信息：</p>
<p><img src="smtp1.jpg" /></p>

<p>如果我们本机没有 sendmail 访问，也可以使用其他服务商的 SMTP 访问（QQ、网易、Google等）。</p>
<pre>
#!/usr/bin/python3

import smtplib
from email.mime.text import MIMEText
from email.header import Header

# 第三方 SMTP 服务
mail_host="smtp.XXX.com"  #设置服务器
mail_user="XXXX"    #用户名
mail_pass="XXXXXX"   #口令 


sender = 'from@runoob.com'
receivers = ['429240967@qq.com']  # 接收邮件，可设置为你的QQ邮箱或者其他邮箱

message = MIMEText('Python 邮件发送测试...', 'plain', 'utf-8')
message['From'] = Header("菜鸟教程", 'utf-8')
message['To'] =  Header("测试", 'utf-8')

subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')


try:
    smtpObj = smtplib.SMTP() 
    smtpObj.connect(mail_host, 25)    # 25 为 SMTP 端口号
    smtpObj.login(mail_user,mail_pass)
    smtpObj.sendmail(sender, receivers, message.as_string())
    print ("邮件发送成功")
except smtplib.SMTPException:
    print ("Error: 无法发送邮件")
</pre>
<hr>
<h2>使用Python发送HTML格式的邮件</h2>
<p>Python发送HTML格式的邮件与发送纯文本消息的邮件不同之处就是将MIMEText中_subtype设置为html。具体代码如下：</p>
<pre>
#!/usr/bin/python3

import smtplib
from email.mime.text import MIMEText
from email.header import Header

sender = 'from@runoob.com'
receivers = ['429240967@qq.com']  # 接收邮件，可设置为你的QQ邮箱或者其他邮箱

mail_msg = """
&lt;p&gt;Python 邮件发送测试...&lt;/p&gt;
&lt;p&gt;&lt;a href="#"&gt;这是一个链接&lt;/a&gt;&lt;/p&gt;
"""
message = MIMEText(mail_msg, 'html', 'utf-8')
message['From'] = Header("菜鸟教程", 'utf-8')
message['To'] =  Header("测试", 'utf-8')

subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')


try:
    smtpObj = smtplib.SMTP('localhost')
    smtpObj.sendmail(sender, receivers, message.as_string())
    print ("邮件发送成功")
except smtplib.SMTPException:
    print ("Error: 无法发送邮件")
</pre>
<p>执行以上程序，如果你本机安装sendmail，就会输出：</p>
<pre>
$ python3 test.py 
邮件发送成功
</pre>
<p>查看我们的收件箱(一般在垃圾箱)，就可以查看到邮件信息：</p>
<p><img src="smtp2.jpg" /></p>
<hr>
<h2>Python 发送带附件的邮件</h2>
<p>发送带附件的邮件，首先要创建MIMEMultipart()实例，然后构造附件，如果有多个附件，可依次构造，最后利用smtplib.smtp发送。</p>
<pre>
#!/usr/bin/python3

import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from email.header import Header

sender = 'from@runoob.com'
receivers = ['429240967@qq.com']  # 接收邮件，可设置为你的QQ邮箱或者其他邮箱

#创建一个带附件的实例
message = MIMEMultipart()
message['From'] = Header("菜鸟教程", 'utf-8')
message['To'] =  Header("测试", 'utf-8')
subject = 'Python SMTP 邮件测试'
message['Subject'] = Header(subject, 'utf-8')

#邮件正文内容
message.attach(MIMEText('这是菜鸟教程Python 邮件发送测试&hellip;&hellip;', 'plain', 'utf-8'))

# 构造附件1，传送当前目录下的 test.txt 文件
att1 = MIMEText(open('test.txt', 'rb').read(), 'base64', 'utf-8')
att1["Content-Type"] = 'application/octet-stream'
# 这里的filename可以任意写，写什么名字，邮件中显示什么名字
att1["Content-Disposition"] = 'attachment; filename="test.txt"'
message.attach(att1)

# 构造附件2，传送当前目录下的 runoob.txt 文件
att2 = MIMEText(open('runoob.txt', 'rb').read(), 'base64', 'utf-8')
att2["Content-Type"] = 'application/octet-stream'
att2["Content-Disposition"] = 'attachment; filename="runoob.txt"'
message.attach(att2)

try:
    smtpObj = smtplib.SMTP('localhost')
    smtpObj.sendmail(sender, receivers, message.as_string())
    print ("邮件发送成功")
except smtplib.SMTPException:
    print ("Error: 无法发送邮件")
</pre>

<pre>
$ python3 test.py 
邮件发送成功
</pre>
<p>查看我们的收件箱(一般在垃圾箱)，就可以查看到邮件信息：</p>
<p><img src="smtp3.jpg" /></p>

<hr><h2>在 HTML 文本中添加图片</h2>
<p>邮件的 HTML 文本中一般邮件服务商添加外链是无效的，正确添加突破的实例如下所示：</p>
<pre>
#!/usr/bin/python3

import smtplib
from email.mime.image import MIMEImage
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from email.header import Header

sender = 'from@runoob.com'
receivers = ['429240967@qq.com']  # 接收邮件，可设置为你的QQ邮箱或者其他邮箱

msgRoot = MIMEMultipart('related')
msgRoot['From'] = Header("菜鸟教程", 'utf-8')
msgRoot['To'] =  Header("测试", 'utf-8')
subject = 'Python SMTP 邮件测试'
msgRoot['Subject'] = Header(subject, 'utf-8')

msgAlternative = MIMEMultipart('alternative')
msgRoot.attach(msgAlternative)


mail_msg = """
&lt;p&gt;Python 邮件发送测试...&lt;/p&gt;
&lt;p&gt;&lt;a href="#"&gt;菜鸟教程链接&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;图片演示：&lt;/p&gt;
&lt;p&gt;&lt;img src="cid:image1"&gt;&lt;/p&gt;
"""
msgAlternative.attach(MIMEText(mail_msg, 'html', 'utf-8'))

# 指定图片为当前目录
fp = open('test.png', 'rb')
msgImage = MIMEImage(fp.read())
fp.close()

# 定义图片 ID，在 HTML 文本中引用
msgImage.add_header('Content-ID', '&lt;image1&gt;')
msgRoot.attach(msgImage)

try:
    smtpObj = smtplib.SMTP('localhost')
    smtpObj.sendmail(sender, receivers, msgRoot.as_string())
    print ("邮件发送成功")
except smtplib.SMTPException:
    print ("Error: 无法发送邮件")
</pre>
<pre>
$ python3 test.py 
邮件发送成功
</pre>
<p>查看我们的收件箱(如果在垃圾箱可能需要移动到收件箱才可正常显示)，就可以查看到邮件信息：</p>
<p><img src="smtp4.jpg" /></p>

<p>更多内容请参阅：<a href="#" target="_blank">https://docs.python.org/3/library/email-examples.html</a>。</p>			
			
			</div></div><div data-role='page' id='multithreading.html'><div data-role='header'><h1>多线程</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('xml-processing.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 多线程</h1>
<p>多线程类似于同时执行多个不同程序，多线程运行有如下优点：</p>
<ul>
<li>使用线程可以把占据长时间的程序中的任务放到后台去处理。</li>
<li>用户界面可以更加吸引人，这样比如用户点击了一个按钮去触发某些事件的处理，可以弹出一个进度条来显示处理的进度</li>
<li>程序的运行速度可能加快</li>
<li>在一些等待的任务实现上如用户输入、文件读写和网络收发数据等，线程就比较有用了。在这种情况下我们可以释放一些珍贵的资源如内存占用等等。</li>
</ul>
<p>线程在执行过程中与进程还是有区别的。每个独立的线程有一个程序运行的入口、顺序执行序列和程序的出口。但是线程不能够独立执行，必须依存在应用程序中，由应用程序提供多个线程执行控制。
</p>
<p>每个线程都有他自己的一组CPU寄存器，称为线程的上下文，该上下文反映了线程上次运行该线程的CPU寄存器的状态。
</p><p>指令指针和堆栈指针寄存器是线程上下文中两个最重要的寄存器，线程总是在进程得到上下文中运行的，这些地址都用于标志拥有线程的进程地址空间中的内存。
</p>
<ul>

<li>线程可以被抢占（中断）。</li>
<li>在其他线程正在运行时，线程可以暂时搁置（也称为睡眠） -- 这就是线程的退让。
</li>
</ul>
<p>线程可以分为:</p>

<ul>
<li><strong>内核线程：</strong>由操作系统内核创建和撤销。</b></li>
<li><strong>用户线程：</strong>不需要内核支持而在用户程序中实现的线程。</b></li>
</ul>

<p>Python3 线程中常用的两个模块为：</p>
<ul>
<li><b>_thread</b></li>
<li><b>threading(推荐使用)</b></li>
</ul>
<p> thread 模块已被废弃。用户可以使用 threading 模块代替。所以，在 Python3 中不能再使用"thread" 模块。为了兼容性，Python3 将 thread 重命名为 "_thread"。 </p>
<br>
<h2>开始学习Python线程</h2>
<p>Python中使用线程有两种方式：函数或者用类来包装线程对象。</p>
<p>函数式：调用 _thread 模块中的start_new_thread()函数来产生新线程。语法如下:</p>
<pre>
_thread.start_new_thread ( function, args[, kwargs] )
</pre>
<p>参数说明:</p>
<ul>
<li>function - 线程函数。</li>
<li>args - 传递给线程函数的参数,他必须是个tuple类型。</li>
<li>kwargs - 可选参数。</li>
</ul>
<p>实例：</p>
<pre>
#!/usr/bin/python3

import _thread
import time

# 为线程定义一个函数
def print_time( threadName, delay):
   count = 0
   while count &lt; 5:
      time.sleep(delay)
      count += 1
      print ("%s: %s" % ( threadName, time.ctime(time.time()) ))

# 创建两个线程
try:
   _thread.start_new_thread( print_time, ("Thread-1", 2, ) )
   _thread.start_new_thread( print_time, ("Thread-2", 4, ) )
except:
   print ("Error: 无法启动线程")

while 1:
   pass
</pre>
<p>执行以上程序输出结果如下：</p>
<pre>
Thread-1: Wed Apr  6 11:36:31 2016
Thread-1: Wed Apr  6 11:36:33 2016
Thread-2: Wed Apr  6 11:36:33 2016
Thread-1: Wed Apr  6 11:36:35 2016
Thread-1: Wed Apr  6 11:36:37 2016
Thread-2: Wed Apr  6 11:36:37 2016
Thread-1: Wed Apr  6 11:36:39 2016
Thread-2: Wed Apr  6 11:36:41 2016
Thread-2: Wed Apr  6 11:36:45 2016
Thread-2: Wed Apr  6 11:36:49 2016
</pre>
<p>执行以上程后可以按下 ctrl-c to 退出。</p>


<p>
<hr>
<h2>线程模块</h2>
<p>Python3 通过两个标准库 _thread 和 threading 提供对线程的支持。</p><p>
_thread 提供了低级别的、原始的线程以及一个简单的锁，它相比于 threading 模块的功能还是比较有限的。</p>
<p>threading 模块除了包含 _thread 模块中的所有方法外，还提供的其他方法： </p>
<ul>
<li>threading.currentThread(): 返回当前的线程变量。 </li>
<li>threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前，不包括启动前和终止后的线程。 </li>
<li>threading.activeCount(): 返回正在运行的线程数量，与len(threading.enumerate())有相同的结果。</li>
</ul>
<p>除了使用方法外，线程模块同样提供了Thread类来处理线程，Thread类提供了以下方法:</p>
<ul>
<li><b>run():</b> 用以表示线程活动的方法。</li>
<li><b>start():</b>启动线程活动。</p></li>
<li><b> join([time]):</b> 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。</li>
<li><b> isAlive():</b> 返回线程是否活动的。</li>
<li><b> getName():</b> 返回线程名。</li>
<li><b> setName():</b> 设置线程名。</li>
</ul>
<hr>
<h2>使用 threading 模块创建线程</h2>
<p>我们可以通过直接从 threading.Thread 继承创建一个新的子类，并实例化后调用 start() 方法启动新线程，即它调用了线程的 run()  方法：</p>
<pre>
#!/usr/bin/python3

import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print ("开始线程：" + self.name)
        print_time(self.name, self.counter, 5)
        print ("退出线程：" + self.name)

def print_time(threadName, delay, counter):
    while counter:
        if exitFlag:
            threadName.exit()
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print ("退出主线程")
</pre>
<p>以上程序执行结果如下；</p>
<pre>
开始线程：Thread-1
开始线程：Thread-2
Thread-1: Wed Apr  6 11:46:46 2016
Thread-1: Wed Apr  6 11:46:47 2016
Thread-2: Wed Apr  6 11:46:47 2016
Thread-1: Wed Apr  6 11:46:48 2016
Thread-1: Wed Apr  6 11:46:49 2016
Thread-2: Wed Apr  6 11:46:49 2016
Thread-1: Wed Apr  6 11:46:50 2016
退出线程：Thread-1
Thread-2: Wed Apr  6 11:46:51 2016
Thread-2: Wed Apr  6 11:46:53 2016
Thread-2: Wed Apr  6 11:46:55 2016
退出线程：Thread-2
退出主线程
</pre>
<hr>
<h2>线程同步</h2>
<p>如果多个线程共同对某个数据修改，则可能出现不可预料的结果，为了保证数据的正确性，需要对多个线程进行同步。
</p>
<p>
使用 Thread 对象的 Lock 和 Rlock 可以实现简单的线程同步，这两个对象都有 acquire 方法和 release 方法，对于那些需要每次只允许一个线程操作的数据，可以将其操作放到 acquire 和 release 方法之间。如下：
</p>
<p>多线程的优势在于可以同时运行多个任务（至少感觉起来是这样）。但是当线程需要共享数据时，可能存在数据不同步的问题。</p>
<p>
考虑这样一种情况：一个列表里所有元素都是0，线程"set"从后向前把所有元素改成1，而线程"print"负责从前往后读取列表并打印。</p>
<p>
那么，可能线程"set"开始改的时候，线程"print"便来打印列表了，输出就成了一半0一半1，这就是数据的不同步。为了避免这种情况，引入了锁的概念。
</p>
<p>
锁有两种状态——锁定和未锁定。每当一个线程比如"set"要访问共享数据时，必须先获得锁定；如果已经有别的线程比如"print"获得锁定了，那么就让线程"set"暂停，也就是同步阻塞；等到线程"print"访问完毕，释放锁以后，再让线程"set"继续。
</p>
<p>
经过这样的处理，打印列表时要么全部输出0，要么全部输出1，不会再出现一半0一半1的尴尬场面。</p>
<p>实例：</p>
<pre>
#!/usr/bin/python3

import threading
import time

class myThread (threading.Thread):
    def __init__(self, threadID, name, counter):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.counter = counter
    def run(self):
        print ("开启线程： " + self.name)
        # 获取锁，用于线程同步
        threadLock.acquire()
        print_time(self.name, self.counter, 3)
        # 释放锁，开启下一个线程
        threadLock.release()

def print_time(threadName, delay, counter):
    while counter:
        time.sleep(delay)
        print ("%s: %s" % (threadName, time.ctime(time.time())))
        counter -= 1

threadLock = threading.Lock()
threads = []

# 创建新线程
thread1 = myThread(1, "Thread-1", 1)
thread2 = myThread(2, "Thread-2", 2)

# 开启新线程
thread1.start()
thread2.start()

# 添加线程到线程列表
threads.append(thread1)
threads.append(thread2)

# 等待所有线程完成
for t in threads:
    t.join()
print ("退出主线程")
</pre>
<p>执行以上程序，输出结果为：</p>
<pre>
开启线程： Thread-1
开启线程： Thread-2
Thread-1: Wed Apr  6 11:52:57 2016
Thread-1: Wed Apr  6 11:52:58 2016
Thread-1: Wed Apr  6 11:52:59 2016
Thread-2: Wed Apr  6 11:53:01 2016
Thread-2: Wed Apr  6 11:53:03 2016
Thread-2: Wed Apr  6 11:53:05 2016
退出主线程
</pre>
<hr>
<h2>线程优先级队列（ Queue）
</h2>
<p>Python 的 Queue 模块中提供了同步的、线程安全的队列类，包括FIFO（先入先出)队列Queue，LIFO（后入先出）队列LifoQueue，和优先级队列 PriorityQueue。
</p><p>这些队列都实现了锁原语，能够在多线程中直接使用，可以使用队列来实现线程间的同步。</p>

<p>Queue 模块中的常用方法:<p>
<ul>
<li>Queue.qsize() 返回队列的大小 </li>
<li>Queue.empty() 如果队列为空，返回True,反之False </li>
<li>Queue.full() 如果队列满了，返回True,反之False</li>
<li>Queue.full 与 maxsize 大小对应 </li>
<li>Queue.get([block[, timeout]])获取队列，timeout等待时间 </li>
<li>Queue.get_nowait() 相当Queue.get(False)</li>
<li>Queue.put(item) 写入队列，timeout等待时间 </li>
<li>Queue.put_nowait(item) 相当Queue.put(item, False)</li>
<li>Queue.task_done() 在完成一项工作之后，Queue.task_done()函数向任务已经完成的队列发送一个信号</li>
<li>Queue.join() 实际上意味着等到队列为空，再执行别的操作</li>
</ul>
<p>实例:</p>
<pre>
#!/usr/bin/python3

import queue
import threading
import time

exitFlag = 0

class myThread (threading.Thread):
    def __init__(self, threadID, name, q):
        threading.Thread.__init__(self)
        self.threadID = threadID
        self.name = name
        self.q = q
    def run(self):
        print ("开启线程：" + self.name)
        process_data(self.name, self.q)
        print ("退出线程：" + self.name)

def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
            queueLock.release()
            print ("%s processing %s" % (threadName, data))
        else:
            queueLock.release()
        time.sleep(1)

threadList = ["Thread-1", "Thread-2", "Thread-3"]
nameList = ["One", "Two", "Three", "Four", "Five"]
queueLock = threading.Lock()
workQueue = queue.Queue(10)
threads = []
threadID = 1

# 创建新线程
for tName in threadList:
    thread = myThread(threadID, tName, workQueue)
    thread.start()
    threads.append(thread)
    threadID += 1

# 填充队列
queueLock.acquire()
for word in nameList:
    workQueue.put(word)
queueLock.release()

# 等待队列清空
while not workQueue.empty():
    pass

# 通知线程是时候退出
exitFlag = 1

# 等待所有线程完成
for t in threads:
    t.join()
print ("退出主线程")
</pre>
<p>以上程序执行结果：</p>

<pre>
开启线程：Thread-1
开启线程：Thread-2
开启线程：Thread-3
Thread-3 processing One
Thread-1 processing Two
Thread-2 processing Three
Thread-3 processing Four
Thread-1 processing Five
退出线程：Thread-3
退出线程：Thread-2
退出线程：Thread-1
退出主线程
</pre>			
			
			</div></div><div data-role='page' id='xml-processing.html'><div data-role='header'><h1>XML解析</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('json.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 XML解析</h1>
<hr>

<h2>什么是XML？</h2>
<p>XML 指可扩展标记语言（e<b>X</b>tensible <b>M</b>arkup <b>L</b>anguage），标准通用标记语言的子集，是一种用于标记电子文件使其具有结构性的标记语言。
你可以通过本站学习<a href="/xml/xml-tutorial.html" target="_blank" title="XML教程">XML教程</a>
</p>
<p>XML 被设计用来传输和存储数据。</p>
<p>XML是一套定义语义标记的规则，这些标记将文档分成许多部件并对这些部件加以标识。</p>
<p>它也是元标记语言，即定义了用于定义其他与特定领域有关的、语义的、结构化的标记语言的句法语言。</p>
<hr>
<h2>python对XML的解析</h2>
<p>常见的XML编程接口有DOM和SAX，这两种接口处理XML文件的方式不同，当然使用场合也不同。</p>
<p>python有三种方法解析XML，SAX，DOM，以及ElementTree:</p>
<h3>1.SAX (simple API for XML )</h3>
<p>python 标准库包含SAX解析器，SAX用事件驱动模型，通过在解析XML的过程中触发一个个的事件并调用用户定义的回调函数来处理XML文件。</p>

<h3>2.DOM(Document Object Model)</h3>
<p>将XML数据在内存中解析成一个树，通过对树的操作来操作XML。</p>



<p>本章节使用到的XML实例文件movies.xml内容如下：</p>
<pre>
&lt;collection shelf="New Arrivals"&gt;
&lt;movie title="Enemy Behind"&gt;
   &lt;type&gt;War, Thriller&lt;/type&gt;
   &lt;format&gt;DVD&lt;/format&gt;
   &lt;year&gt;2003&lt;/year&gt;
   &lt;rating&gt;PG&lt;/rating&gt;
   &lt;stars&gt;10&lt;/stars&gt;
   &lt;description&gt;Talk about a US-Japan war&lt;/description&gt;
&lt;/movie&gt;
&lt;movie title="Transformers"&gt;
   &lt;type&gt;Anime, Science Fiction&lt;/type&gt;
   &lt;format&gt;DVD&lt;/format&gt;
   &lt;year&gt;1989&lt;/year&gt;
   &lt;rating&gt;R&lt;/rating&gt;
   &lt;stars&gt;8&lt;/stars&gt;
   &lt;description&gt;A schientific fiction&lt;/description&gt;
&lt;/movie&gt;
   &lt;movie title="Trigun"&gt;
   &lt;type&gt;Anime, Action&lt;/type&gt;
   &lt;format&gt;DVD&lt;/format&gt;
   &lt;episodes&gt;4&lt;/episodes&gt;
   &lt;rating&gt;PG&lt;/rating&gt;
   &lt;stars&gt;10&lt;/stars&gt;
   &lt;description&gt;Vash the Stampede!&lt;/description&gt;
&lt;/movie&gt;
&lt;movie title="Ishtar"&gt;
   &lt;type&gt;Comedy&lt;/type&gt;
   &lt;format&gt;VHS&lt;/format&gt;
   &lt;rating&gt;PG&lt;/rating&gt;
   &lt;stars&gt;2&lt;/stars&gt;
   &lt;description&gt;Viewable boredom&lt;/description&gt;
&lt;/movie&gt;
&lt;/collection&gt;
</pre>
<hr>
<h2>python使用SAX解析xml</h2>
<p>SAX是一种基于事件驱动的API。</p>
<p>利用SAX解析XML文档牵涉到两个部分:解析器和事件处理器。</p>
<p>解析器负责读取XML文档,并向事件处理器发送事件,如元素开始跟元素结束事件;</p>
<p>而事件处理器则负责对事件作出相应,对传递的XML数据进行处理。
</p>
<pSAX适于处理下面的问题：</p>
<ul>
<li>
1、对大型文件进行处理；</li><li>
2、只需要文件的部分内容，或者只需从文件中得到特定信息。</li><li>
3、想建立自己的对象模型的时候。</li></ul>
<p>在python中使用sax方式处理xml要先引入xml.sax中的parse函数，还有xml.sax.handler中的ContentHandler。</p>
<h3>ContentHandler类方法介绍</h3>
<p><strong>characters(content)方法</strong></p>
<p>调用时机：</p>
<p>从行开始，遇到标签之前，存在字符，content的值为这些字符串。</p>
<p>从一个标签，遇到下一个标签之前， 存在字符，content的值为这些字符串。</p>
<p>从一个标签，遇到行结束符之前，存在字符，content的值为这些字符串。</p>
<p>标签可以是开始标签，也可以是结束标签。</p>


<p><strong>startDocument()方法</strong></p>
<p>文档启动的时候调用。</p>


<p><strong>endDocument()方法</strong></p>
<p>解析器到达文档结尾时调用。</p>


<p><strong>startElement(name, attrs)方法</strong></p>
<p>遇到XML开始标签时调用，name是标签的名字，attrs是标签的属性值字典。</p>


<p><strong>endElement(name)方法</strong></p>
<p>遇到XML结束标签时调用。 </p>
<hr>
<h2>make_parser方法</h2>
<p>以下方法创建一个新的解析器对象并返回。</p>
<pre>
xml.sax.make_parser( [parser_list] )
</pre>
<p>参数说明:</p>
<ul>
<li><strong>parser_list</strong> - 
可选参数，解析器列表</li>
</ul>
<hr>
<h2>parser方法</h2>
<p>以下方法创建一个 SAX 解析器并解析xml文档：</p>
<pre>
xml.sax.parse( xmlfile, contenthandler[, errorhandler])
</pre>
<p>参数说明:</p>
<ul>
<li><strong>xmlfile</strong> - 
xml文件名</li>
<li><strong>contenthandler</strong> - 
必须是一个ContentHandler的对象</li>
<li><strong>errorhandler</strong> - 
如果指定该参数，errorhandler必须是一个SAX ErrorHandler对象</li>
</ul>
<hr>
<h2>parseString方法</h2>
<p>parseString方法创建一个XML解析器并解析xml字符串：</p>
<pre>
xml.sax.parseString(xmlstring, contenthandler[, errorhandler])
</pre>
<p>参数说明:</p>
<ul>
<li><strong>xmlstring</strong> - 
xml字符串</li>
<li><strong>contenthandler</strong> - 
必须是一个ContentHandler的对象</li>
<li><strong>errorhandler</strong> - 
如果指定该参数，errorhandler必须是一个SAX ErrorHandler对象</li>
</ul>
<hr>
<h2>Python 解析XML实例</h2>
<pre>
#!/usr/bin/python3

import xml.sax

class MovieHandler( xml.sax.ContentHandler ):
   def __init__(self):
      self.CurrentData = ""
      self.type = ""
      self.format = ""
      self.year = ""
      self.rating = ""
      self.stars = ""
      self.description = ""

   # 元素开始调用
   def startElement(self, tag, attributes):
      self.CurrentData = tag
      if tag == "movie":
         print ("*****Movie*****")
         title = attributes["title"]
         print ("Title:", title)

   # 元素结束调用
   def endElement(self, tag):
      if self.CurrentData == "type":
         print ("Type:", self.type)
      elif self.CurrentData == "format":
         print ("Format:", self.format)
      elif self.CurrentData == "year":
         print ("Year:", self.year)
      elif self.CurrentData == "rating":
         print ("Rating:", self.rating)
      elif self.CurrentData == "stars":
         print ("Stars:", self.stars)
      elif self.CurrentData == "description":
         print ("Description:", self.description)
      self.CurrentData = ""

   # 读取字符时调用
   def characters(self, content):
      if self.CurrentData == "type":
         self.type = content
      elif self.CurrentData == "format":
         self.format = content
      elif self.CurrentData == "year":
         self.year = content
      elif self.CurrentData == "rating":
         self.rating = content
      elif self.CurrentData == "stars":
         self.stars = content
      elif self.CurrentData == "description":
         self.description = content
  
if ( __name__ == "__main__"):
   
   # 创建一个 XMLReader
   parser = xml.sax.make_parser()
   # turn off namepsaces
   parser.setFeature(xml.sax.handler.feature_namespaces, 0)

   # 重写 ContextHandler
   Handler = MovieHandler()
   parser.setContentHandler( Handler )
   
   parser.parse("movies.xml")
</pre>
<p>以上代码执行结果如下：</p>
<pre>
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Year: 2003
Rating: PG
Stars: 10
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Year: 1989
Rating: R
Stars: 8
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Stars: 10
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Stars: 2
Description: Viewable boredom
</pre>
<p>完整的 SAX API 文档请查阅<a href="#" target="_blank" rel="nofollow">Python SAX APIs</a></p>
<hr>
<h2>使用xml.dom解析xml</h2>
<p>文件对象模型（Document Object Model，简称DOM），是W3C组织推荐的处理可扩展置标语言的标准编程接口。</p>
<p>一个 DOM 的解析器在解析一个 XML 文档时，一次性读取整个文档，把文档中所有元素保存在内存中的一个树结构里，之后你可以利用DOM 提供的不同的函数来读取或修改文档的内容和结构，也可以把修改过的内容写入xml文件。
</p>
<p> python中用xml.dom.minidom来解析xml文件，实例如下：</p>
<pre>
#!/usr/bin/python3

from xml.dom.minidom import parse
import xml.dom.minidom

# 使用minidom解析器打开 XML 文档
DOMTree = xml.dom.minidom.parse("movies.xml")
collection = DOMTree.documentElement
if collection.hasAttribute("shelf"):
   print ("Root element : %s" % collection.getAttribute("shelf"))

# 在集合中获取所有电影
movies = collection.getElementsByTagName("movie")

# 打印每部电影的详细信息
for movie in movies:
   print ("*****Movie*****")
   if movie.hasAttribute("title"):
      print ("Title: %s" % movie.getAttribute("title"))

   type = movie.getElementsByTagName('type')[0]
   print ("Type: %s" % type.childNodes[0].data)
   format = movie.getElementsByTagName('format')[0]
   print ("Format: %s" % format.childNodes[0].data)
   rating = movie.getElementsByTagName('rating')[0]
   print ("Rating: %s" % rating.childNodes[0].data)
   description = movie.getElementsByTagName('description')[0]
   print ("Description: %s" % description.childNodes[0].data)
</pre>
<p>以上程序执行结果如下：</p>
<pre>
Root element : New Arrivals
*****Movie*****
Title: Enemy Behind
Type: War, Thriller
Format: DVD
Rating: PG
Description: Talk about a US-Japan war
*****Movie*****
Title: Transformers
Type: Anime, Science Fiction
Format: DVD
Rating: R
Description: A schientific fiction
*****Movie*****
Title: Trigun
Type: Anime, Action
Format: DVD
Rating: PG
Description: Vash the Stampede!
*****Movie*****
Title: Ishtar
Type: Comedy
Format: VHS
Rating: PG
Description: Viewable boredom
</pre>
<p>完整的  DOM API 文档请查阅<a href="#" target="_blank" rel="nofollow">Python DOM APIs</a>。</p>			
			
			</div></div><div data-role='page' id='json.html'><div data-role='header'><h1>JSON 数据解析</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('date-time.html')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
			
			<h1>Python3 JSON 数据解析</h1>
<p>JSON (JavaScript Object Notation)  是一种轻量级的数据交换格式。它基于ECMAScript的一个子集。</p>
<p>Python3 中可以使用 json 模块来对 JSON 数据进行编解码，它包含了两个函数：</p>
<ul>
<li><b>json.dumps(): </b>对数据进行编码。</li>
<li><b>json.loads(): </b>对数据进行解码。</li>
</ul>
<p>
在json的编解码过程中，python 的原始类型与json类型会相互转换，具体的转化对照如下：</p>
<h3>Python 编码为 JSON 类型转换对应表：</h3>
<table border="1" class="reference">
<colgroup>
<col width="73%">
<col width="27%">
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">Python</th>
<th class="head">JSON</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>dict</td>
<td>object</td>
</tr>
<tr class="row-odd"><td>list, tuple</td>
<td>array</td>
</tr>
<tr class="row-even"><td>str</td>
<td>string</td>
</tr>
<tr class="row-odd"><td>int, float, int- &amp; float-derived Enums</td>
<td>number</td>
</tr>
<tr class="row-even"><td>True</td>
<td>true</td>
</tr>
<tr class="row-odd"><td>False</td>
<td>false</td>
</tr>
<tr class="row-even"><td>None</td>
<td>null</td>
</tr>
</tbody>
</table>

<h3>JSON 解码为 Python 类型转换对应表：</h3>
<table border="1" class="reference">
<colgroup>
<col width="44%">
<col width="56%">
</colgroup>
<thead valign="bottom">
<tr class="row-odd"><th class="head">JSON</th>
<th class="head">Python</th>
</tr>
</thead>
<tbody valign="top">
<tr class="row-even"><td>object</td>
<td>dict</td>
</tr>
<tr class="row-odd"><td>array</td>
<td>list</td>
</tr>
<tr class="row-even"><td>string</td>
<td>str</td>
</tr>
<tr class="row-odd"><td>number (int)</td>
<td>int</td>
</tr>
<tr class="row-even"><td>number (real)</td>
<td>float</td>
</tr>
<tr class="row-odd"><td>true</td>
<td>True</td>
</tr>
<tr class="row-even"><td>false</td>
<td>False</td>
</tr>
<tr class="row-odd"><td>null</td>
<td>None</td>
</tr>
</tbody>
</table>
<h3>json.dumps 与 json.loads 实例</h3>
<p>以下实例演示了 Python 数据结构转换为JSON：</p>
<pre>
#!/usr/bin/python3

import json

# Python 字典类型转换为 JSON 对象
data = {
    'no' : 1,
    'name' : 'Runoob',
    'url' : 'http://www.runoob.com'
}

json_str = json.dumps(data)
print ("Python 原始数据：", repr(data))
print ("JSON 对象：", json_str)
</pre>
<p>执行以上代码输出结果为：</p>
<pre>
Python 原始数据： {'url': 'http://www.runoob.com', 'no': 1, 'name': 'Runoob'}
JSON 对象： {"url": "http://www.runoob.com", "no": 1, "name": "Runoob"}
</pre>
<p>通过输出的结果可以看出，简单类型通过编码后跟其原始的repr()输出结果非常相似。</p>
<p>接着以上实例，我们可以将一个JSON编码的字符串转换回一个Python数据结构：</p>
<pre>
#!/usr/bin/python3

import json

# Python 字典类型转换为 JSON 对象
data1 = {
    'no' : 1,
    'name' : 'Runoob',
    'url' : 'http://www.runoob.com'
}

json_str = json.dumps(data1)
print ("Python 原始数据：", repr(data1))
print ("JSON 对象：", json_str)

# 将 JSON 对象转换为 Python 字典
data2 = json.loads(json_str)
print ("data2['name']: ", data2['name'])
print ("data2['url']: ", data2['url'])
</pre>
<p>执行以上代码输出结果为：</p>
<pre>
ython 原始数据： {'name': 'Runoob', 'no': 1, 'url': 'http://www.runoob.com'}
JSON 对象： {"name": "Runoob", "no": 1, "url": "http://www.runoob.com"}
data2['name']:  Runoob
data2['url']:  http://www.runoob.com
</pre>
<p>如果你要处理的是文件而不是字符串，你可以使用 <b>json.dump()</b> 和 <b>json.load()</b> 来编码和解码JSON数据。例如：</p>
<pre>
# 写入 JSON 数据
with open('data.json', 'w') as f:
    json.dump(data, f)

# 读取数据
with open('data.json', 'r') as f:
    data = json.load(f)
</pre>
<p>更多资料请参考：<a href="#" target="_blank">https://docs.python.org/3/library/json.html</a>			
			
			</div></div><div data-role='page' id='date-time.html'><div data-role='header'><h1>日期和时间</h1><a href='#leftpanel3' class='jqm-navmenu-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-bars ui-nodisc-icon ui-alt-icon ui-btn-left'>Menu</a><a href='#' onclick="navNext('#')" class='jqm-search-link ui-btn ui-btn-icon-notext ui-corner-all ui-icon-arrow-r ui-nodisc-icon ui-alt-icon ui-btn-right'>Search</a></div><div role='main' class='ui-content jqm-content'>
<h1>Python3 <span class="color_h1">日期和时间</span></h1>
<p>Python 程序能用很多方式处理日期和时间，转换日期格式是一个常见的功能。</p>
<p>Python 提供了一个 time 和 calendar 模块可以用于格式化日期和时间。</p>
<p>时间间隔是以秒为单位的浮点小数。</p>
<p>每个时间戳都以自从1970年1月1日午夜（历元）经过了多长时间来表示。</p>
<p>Python 的 time 模块下有很多函数可以转换常见日期格式。如函数time.time()用于获取当前时间戳, 如下实例:<p>
<pre>
#!/usr/bin/python3

import time;  # 引入time模块

ticks = time.time()
print ("当前时间戳为:", ticks)
</pre>
<p>以上实例输出结果：</p>
<pre>
当前时间戳为: 1459996086.7115328
</pre>
<p>
时间戳单位最适于做日期运算。但是1970年之前的日期就无法以此表示了。太遥远的日期也不行，UNIX和Windows只支持到2038年。
</p>
<br><hr>
<h2>什么是时间元组？</h2>
<p>很多Python函数用一个元组装起来的9组数字处理时间:</p>
<table class="reference">
<tbody><tr>
<th style="width:10%">序号
</th><th style="width:40%">字段</th><th>值</th>
</tr>
<tr><td>0</td><td>4位数年</td><td>2008</td></tr>
<tr><td>1</td><td>月</td><td>1 到 12</td></tr>
<tr><td>2</td><td>日</td><td>1到31</td></tr>
<tr><td>3</td><td>小时</td><td>0到23</td></tr>
<tr><td>4</td><td>分钟</td><td>0到59</td></tr>
<tr><td>5</td><td>秒</td><td>0到61 (60或61 是闰秒)</td></tr>
<tr><td>6</td><td>一周的第几日</td><td>0到6 (0是周一)</td></tr>
<tr><td>7</td><td>一年的第几日</td><td>1到366 (儒略历)</td></tr>
<tr><td>8</td><td>夏令时</td><td>-1, 0, 1, -1是决定是否为夏令时的旗帜</td></tr>
</tbody></table>
<p>上述也就是struct_time元组。这种结构具有如下属性：</p>
<table class="reference">
<tbody><tr>
<th style="width:10%">序号</th><th style="width:40%">属性</th><th>值</th>
</tr>
<tr><td>0</td><td>tm_year</td><td>2008</td></tr>
<tr><td>1</td><td>tm_mon</td><td>1 到 12</td></tr>
<tr><td>2</td><td>tm_mday</td><td>1 到 31</td></tr>
<tr><td>3</td><td>tm_hour</td><td>0 到 23</td></tr>
<tr><td>4</td><td>tm_min</td><td>0 到 59</td></tr>
<tr><td>5</td><td>tm_sec</td><td>0 到 61 (60或61 是闰秒)</td></tr>
<tr><td>6</td><td>tm_wday</td><td>0到6 (0是周一)</td></tr>
<tr><td>7</td><td>tm_yday</td><td>1 到 366(儒略历)</td></tr>
<tr><td>8</td><td>tm_isdst</td><td>-1, 0, 1, -1是决定是否为夏令时的旗帜</td></tr>
</tbody></table>
<br><hr>
<h2>获取当前时间</h2>
<p>从返回浮点数的时间辍方式向时间元组转换，只要将浮点数传递给如localtime之类的函数。</p>
<pre>
#!/usr/bin/python3

import time

localtime = time.localtime(time.time())
print ("本地时间为 :", localtime)
</pre>
<p>以上实例输出结果：</p>
<pre>
本地时间为 : time.struct_time(tm_year=2016, tm_mon=4, tm_mday=7, tm_hour=10, tm_min=28, tm_sec=49, tm_wday=3, tm_yday=98, tm_isdst=0)
</pre>
<br><hr>
<h2>获取格式化的时间</h2>
<p>你可以根据需求选取各种格式，但是最简单的获取可读的时间模式的函数是asctime():</p>
<pre>
#!/usr/bin/python3

import time

localtime = time.asctime( time.localtime(time.time()) )
print ("本地时间为 :", localtime)
</pre>
<p>以上实例输出结果：</p>
<pre>
本地时间为 : Thu Apr  7 10:29:13 2016
</pre>
<hr>
<h2>格式化日期</h2>
<p>我们可以使用 time 模块的 strftime 方法来格式化日期，：</p>
<pre>
time.strftime(format[, t])
</pre>
<pre>
#!/usr/bin/python3

import time

# 格式化成2016-03-20 11:45:39形式
print (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

# 格式化成Sat Mar 28 22:24:24 2016形式
print (time.strftime("%a %b %d %H:%M:%S %Y", time.localtime()))
  
# 将格式字符串转换为时间戳
a = "Sat Mar 28 22:24:24 2016"
print (time.mktime(time.strptime(a,"%a %b %d %H:%M:%S %Y")))
</pre>
<p>以上实例输出结果：</p>
<pre>
2016-04-07 10:29:46
Thu Apr 07 10:29:46 2016
1459175064.0
</pre>
<p>python中时间日期格式化符号：</p>
<ul> <li>%y 两位数的年份表示（00-99）</li> <li>%Y 四位数的年份表示（000-9999）</li> <li>%m 月份（01-12）</li> <li>%d 月内中的一天（0-31）</li> <li>%H 24小时制小时数（0-23）</li> <li>%I 12小时制小时数（01-12）</li> <li>%M 分钟数（00=59）</li> <li>%S 秒（00-59）</li> <li>%a 本地简化星期名称</li> <li>%A 本地完整星期名称</li> <li>%b 本地简化的月份名称</li> <li>%B 本地完整的月份名称</li> <li>%c 本地相应的日期表示和时间表示</li> <li>%j 年内的一天（001-366）</li> <li>%p 本地A.M.或P.M.的等价符</li> <li>%U 一年中的星期数（00-53）星期天为星期的开始</li> <li>%w 星期（0-6），星期天为星期的开始</li> <li>%W 一年中的星期数（00-53）星期一为星期的开始</li> <li>%x 本地相应的日期表示</li> <li>%X 本地相应的时间表示</li> <li>%Z 当前时区的名称</li> <li>%% %号本身</li> </ul>
<hr>
<h2>获取某月日历</h2>
<p>Calendar模块有很广泛的方法用来处理年历和月历，例如打印某月的月历：</p>
<pre>
#!/usr/bin/python3

import calendar

cal = calendar.month(2016, 1)
print ("以下输出2016年1月份的日历:")
print (cal)
</pre>
<p>以上实例输出结果：</p>
<pre>
以下输出2016年1月份的日历:
    January 2016
Mo Tu We Th Fr Sa Su
             1  2  3
 4  5  6  7  8  9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30 31
</pre>
<br><hr>
<h2>Time 模块</h2>
<p>Time 模块包含了以下内置函数，既有时间处理相的，也有转换时间格式的：</p>
<table class="reference">
<tbody><tr>
<th style="width:5%">序号</th><th style="width:35%">函数及描述</th><th>实例</th></tr>
<tr><td>1</td><td>time.altzone<br>返回格林威治西部的夏令时地区的偏移秒数。如果该地区在格林威治东部会返回负值（如西欧，包括英国）。对夏令时启用地区才能使用。</td>
<td>
<p>以下实例展示了 altzone()函数的使用方法：</p>
<pre>
&gt;&gt;&gt; import time
&gt;&gt;&gt; print ("time.altzone %d " % time.altzone)
time.altzone -28800 
</pre>
</td>
</tr>
<tr><td>2</td><td>time.asctime([tupletime])<br>接受时间元组并返回一个可读的形式为"Tue Dec 11 18:07:14 2008"（2008年12月11日 周二18时07分14秒）的24个字符的字符串。</td>
<td>
<p>以下实例展示了 asctime()函数的使用方法：</p>
<pre>
&gt;&gt;&gt; import time
&gt;&gt;&gt; t = time.localtime()
&gt;&gt;&gt; print ("time.asctime(t): %s " % time.asctime(t))
time.asctime(t): Thu Apr  7 10:36:20 2016 
</pre>
</td>
</tr>
<tr><td>3</td><td><a href="python3-att-time-clock.html" target="_blank">time.clock()</a><br>用以浮点数计算的秒数返回当前的CPU时间。用来衡量不同程序的耗时，比time.time()更有用。</td><td><a href="python3-att-time-clock.html" target="_blank">实例</a></td></tr>
<tr><td>4</td><td>time.ctime([secs])<br>作用相当于asctime(localtime(secs))，未给参数相当于asctime()</td>
<td>
<p>以下实例展示了 ctime()函数的使用方法：</p>
<pre>
&gt;&gt;&gt; import time
&gt;&gt;&gt; print ("time.ctime() : %s" % time.ctime())
time.ctime() : Thu Apr  7 10:51:58 2016
</pre>
</td>
</tr>
<tr><td>5</td><td>time.gmtime([secs])<br>接收时间辍（1970纪元后经过的浮点秒数）并返回格林威治天文时间下的时间元组t。注：t.tm_isdst始终为0</td>
<td>
<p>以下实例展示了 gmtime()函数的使用方法：</p>
<pre>
&gt;&gt;&gt; import time
&gt;&gt;&gt; print ("gmtime :", time.gmtime(1455508609.34375))
gmtime : time.struct_time(tm_year=2016, tm_mon=2, tm_mday=15, tm_hour=3, tm_min=56, tm_sec=49, tm_wday=0, tm_yday=46, tm_isdst=0)
</pre>
</td>
</tr>
<tr><td>6</td><td>time.localtime([secs]<br>接收时间辍（1970纪元后经过的浮点秒数）并返回当地时间下的时间元组t（t.tm_isdst可取0或1，取决于当地当时是不是夏令时）。</td>
<td>
<p>以下实例展示了 localtime()函数的使用方法：</p>
<pre>
&gt;&gt;&gt; import time
&gt;&gt;&gt; print ("localtime(): ", time.localtime(1455508609.34375))
localtime():  time.struct_time(tm_year=2016, tm_mon=2, tm_mday=15, tm_hour=11, tm_min=56, tm_sec=49, tm_wday=0, tm_yday=46, tm_isdst=0)
</pre>
</td>
</tr>
<tr><td>7</td><td><a href="python3-att-time-mktime.html" target="_blank">time.mktime(tupletime)</a><br>接受时间元组并返回时间辍（1970纪元后经过的浮点秒数）。</td><td><a href="python3-att-time-mktime.html" target="_blank">实例</a></td></tr>
<tr><td>8</td><td>time.sleep(secs)<br>推迟调用线程的运行，secs指秒数。</td>
<td>
<p>以下实例展示了 sleep()函数的使用方法：</p>
<pre>
#!/usr/bin/python3
import time

print ("Start : %s" % time.ctime())
time.sleep( 5 )
print ("End : %s" % time.ctime())
</pre>
</td>
</tr>
<tr><td>9</td><td>time.strftime(fmt[,tupletime])<br>接收以时间元组，并返回以可读字符串表示的当地时间，格式由fmt决定。</td>
<td>
<p>以下实例展示了 strftime()函数的使用方法：</p>
<pre>
&gt;&gt;&gt; import time
&gt;&gt;&gt; print (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
2016-04-07 11:18:05
</pre>
</td>
</tr>
<tr><td>10</td><td>time.strptime(str,fmt='%a %b %d %H:%M:%S %Y')<br>根据fmt的格式把一个时间字符串解析为时间元组。</td>
<td>
<p>以下实例展示了 strftime()函数的使用方法：</p>
<pre>
&gt;&gt;&gt; import time
&gt;&gt;&gt; struct_time = time.strptime("30 Nov 00", "%d %b %y")
&gt;&gt;&gt; print ("返回元组: ", struct_time)
返回元组:  time.struct_time(tm_year=2000, tm_mon=11, tm_mday=30, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=335, tm_isdst=-1)
</pre>
</td>
</tr>
<tr><td>11</td><td>time.time( )<br>返回当前时间的时间戳（1970纪元后经过的浮点秒数）。</td>
<td>
<p>以下实例展示了 time()函数的使用方法：</p>
<pre>
&gt;&gt;&gt; import time
&gt;&gt;&gt; print(time.time())
1459999336.1963577
</pre>
</td>
</tr>
<tr><td>12</td><td><a href="python3-att-time-tzset.html" target="_blank">time.tzset()</a><br>根据环境变量TZ重新初始化时间相关设置。 </td><td><a href="python3-att-time-tzset.html" target="_blank">实例</a></td></tr>
</tbody></table>
<p>Time模块包含了以下2个非常重要的属性：</p>
<table class="reference">
<tbody><tr>
<th style="width:5%">序号</th><th style="width:95%">属性及描述</th></tr>
<tr><td>1</td><td><b>time.timezone</b><br>属性time.timezone是当地时区（未启动夏令时）距离格林威治的偏移秒数（>0，美洲;<=0大部分欧洲，亚洲，非洲）。</td></tr>
<tr><td>2</td><td><b>time.tzname</b><br>属性time.tzname包含一对根据情况的不同而不同的字符串，分别是带夏令时的本地时区名称，和不带的。</td></tr>
</tbody></table>
<br><hr>
<h2>日历（Calendar）模块</h2>
<p>此模块的函数都是日历相关的，例如打印某月的字符月历。</p>
<p>星期一是默认的每周第一天，星期天是默认的最后一天。更改设置需调用calendar.setfirstweekday()函数。模块包含了以下内置函数：</p>
<table class="reference">
<tbody><tr>
<th style="width:5%">序号</th><th style="width:95%">函数及描述</th></tr>
<tr><td>1</td><td><b>calendar.calendar(year,w=2,l=1,c=6)</b><br>返回一个多行字符串格式的year年年历，3个月一行，间隔距离为c。 每日宽度间隔为w字符。每行长度为21* W+18+2* C。l是每星期行数。</td></tr>
<tr><td>2</td><td><b>calendar.firstweekday( )</b><br>返回当前每周起始日期的设置。默认情况下，首次载入caendar模块时返回0，即星期一。</td></tr>
<tr><td>3</td><td><b>calendar.isleap(year)</b><br>是闰年返回True，否则为false。</td></tr>
<tr><td>4</td><td><b>calendar.leapdays(y1,y2)</b><br>返回在Y1，Y2两年之间的闰年总数。</td></tr>
<tr><td>5</td><td><b>calendar.month(year,month,w=2,l=1)</b><br>返回一个多行字符串格式的year年month月日历，两行标题，一周一行。每日宽度间隔为w字符。每行的长度为7* w+6。l是每星期的行数。</td></tr>
<tr><td>6</td><td><b>calendar.monthcalendar(year,month)</b><br>返回一个整数的单层嵌套列表。每个子列表装载代表一个星期的整数。Year年month月外的日期都设为0;范围内的日子都由该月第几日表示，从1开始。</td></tr>
<tr><td>7</td><td><b>calendar.monthrange(year,month)</b><br>返回两个整数。第一个是该月的星期几的日期码，第二个是该月的日期码。日从0（星期一）到6（星期日）;月从1到12。</td></tr>
<tr><td>8</td><td><b>calendar.prcal(year,w=2,l=1,c=6)</b><br>相当于 print calendar.calendar(year,w,l,c).</td></tr>
<tr><td>9</td><td><b>calendar.prmonth(year,month,w=2,l=1)</b><br>相当于 print calendar.calendar（year，w，l，c）。</td></tr>
<tr><td>10</td><td><b>calendar.setfirstweekday(weekday)</b><br>设置每周的起始日期码。0（星期一）到6（星期日）。</td></tr>
<tr><td>11</td><td><b>calendar.timegm(tupletime)</b><br>和time.gmtime相反：接受一个时间元组形式，返回该时刻的时间辍（1970纪元后经过的浮点秒数）。</td></tr>
<tr><td>12</td><td><b>calendar.weekday(year,month,day)</b><br>返回给定日期的日期码。0（星期一）到6（星期日）。月份为 1（一月） 到 12（12月）。</td></tr>
</tbody></table>
<br><hr>
<h2>其他相关模块和函数</h2>
<p>在Python中，其他处理日期和时间的模块还有：</p>
<ul>
<li><a href="#" target="_blank" rel="nofollow">time 模块</a></li>
<li><a href="#" target="_blank" rel="nofollow">datetime模块</a></li>
</ul>
</div></div>
<div data-role='panel' id='leftpanel3' data-position='left' data-display='overlay' data-theme='a'>
<h3>Python 3 教程</h3>
<ul data-role="listview" data-inset="true">
<li><a href='#tutorial.html'>教程</a></li><li><a href='#interpreter.html'>解释器</a></li><li><a href='#comment.html'>注释</a></li><li><a href='#number.html'>数字(Number)</a></li><li><a href='#string.html'>字符串</a></li><li><a href='#list.html'>列表</a></li><li><a href='#step1.html'>编程第一步</a></li><li><a href='#conditional-statements.html'>条件控制</a></li><li><a href='#loop.html'>循环语句</a></li><li><a href='#function.html'>函数</a></li><li><a href='#data-structure.html'>数据结构</a></li><li><a href='#module.html'>模块</a></li><li><a href='#inputoutput.html'>输入和输出</a></li><li><a href='#errors-execptions.html'>错误和异常</a></li><li><a href='#class.html'>面向对象</a></li><li><a href='#stdlib.html'>标准库概览</a></li><li><a href='#examples.html'>实例</a></li><li><a href='#reg-expressions.html'>正则表达式</a></li><li><a href='#cgi-programming.html'>CGI编程</a></li><li><a href='#mysql.html'>MySQL 数据库连接</a></li><li><a href='#socket.html'>网络编程</a></li><li><a href='#smtp.html'>SMTP发送邮件</a></li><li><a href='#multithreading.html'>多线程</a></li><li><a href='#xml-processing.html'>XML解析</a></li><li><a href='#json.html'>JSON 数据解析</a></li><li><a href='#date-time.html'>日期和时间</a></li>
</ul></div>

    </body>

</html>
